pkghandler.pp 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282
  1. {$mode objfpc}
  2. {$h+}
  3. unit pkghandler;
  4. interface
  5. uses
  6. Classes,SysUtils,
  7. pkgglobals,
  8. pkgoptions,
  9. fprepos;
  10. type
  11. { TActionStack }
  12. TActionArgs = array of string;
  13. TActionStackItem = record
  14. ActionPackage : TFPPackage;
  15. Action : string;
  16. Args : TActionArgs;
  17. end;
  18. PActionStackItem = ^TActionStackItem;
  19. TActionStack = class
  20. private
  21. FList : TFPList;
  22. public
  23. constructor Create;
  24. destructor Destroy;override;
  25. procedure Push(APackage:TFPPackage;const AAction:string;const Args:TActionArgs);
  26. procedure Push(APackage:TFPPackage;const AAction:string;const Args:array of string);
  27. function Pop(out APackage:TFPPackage;out AAction:string;out Args:TActionArgs):boolean;
  28. end;
  29. { TPackageHandler }
  30. TPackageHandler = Class(TComponent)
  31. private
  32. FCurrentPackage : TFPPackage;
  33. Protected
  34. Procedure Log(Level: TVerbosity;Msg : String);
  35. Procedure Log(Level: TVerbosity;Fmt : String; const Args : array of const);
  36. Procedure Error(Msg : String);
  37. Procedure Error(Fmt : String; const Args : array of const);
  38. procedure ExecuteAction(APackage:TFPPackage;const AAction:string;const Args:TActionArgs=nil);
  39. Function ExecuteProcess(Const Prog,Args:String):Integer;
  40. Procedure SetCurrentDir(Const ADir:String);
  41. function PackageBuildPath:String;
  42. function PackageRemoteArchive:String;
  43. function PackageLocalArchive:String;
  44. function PackageManifestFile:String;
  45. Public
  46. Constructor Create(AOwner:TComponent;APackage:TFPPackage); virtual;
  47. function PackageLogPrefix:String;
  48. Function Execute(const Args:TActionArgs):boolean; virtual; abstract;
  49. Property CurrentPackage:TFPPackage Read FCurrentPackage Write FCurrentPackage;
  50. end;
  51. TPackageHandlerClass = class of TPackageHandler;
  52. EPackageHandler = Class(Exception);
  53. // Actions/PkgHandler
  54. procedure RegisterPkgHandler(const AAction:string;pkghandlerclass:TPackageHandlerClass);
  55. function GetPkgHandler(const AAction:string):TPackageHandlerClass;
  56. procedure ExecuteAction(APackage:TFPPackage;const AAction:string;const Args:TActionArgs=nil);
  57. Implementation
  58. uses
  59. typinfo,
  60. contnrs,
  61. uriparser,
  62. pkgmessages;
  63. var
  64. PkgHandlerList : TFPHashList;
  65. procedure RegisterPkgHandler(const AAction:string;pkghandlerclass:TPackageHandlerClass);
  66. begin
  67. if PkgHandlerList.Find(AAction)<>nil then
  68. begin
  69. Raise EPackageHandler.CreateFmt(SErrActionAlreadyRegistered,[AAction]);
  70. exit;
  71. end;
  72. PkgHandlerList.Add(AAction,pkghandlerclass);
  73. end;
  74. function GetPkgHandler(const AAction:string):TPackageHandlerClass;
  75. begin
  76. result:=TPackageHandlerClass(PkgHandlerList.Find(AAction));
  77. if result=nil then
  78. Raise EPackageHandler.CreateFmt(SErrActionNotFound,[AAction]);
  79. end;
  80. procedure ExecuteAction(APackage:TFPPackage;const AAction:string;const Args:TActionArgs=nil);
  81. var
  82. pkghandlerclass : TPackageHandlerClass;
  83. i : integer;
  84. logargs : string;
  85. begin
  86. pkghandlerclass:=GetPkgHandler(AAction);
  87. With pkghandlerclass.Create(nil,APackage) do
  88. try
  89. logargs:='';
  90. for i:=Low(Args) to High(Args) do
  91. begin
  92. if logargs='' then
  93. logargs:=Args[i]
  94. else
  95. logargs:=logargs+','+Args[i];
  96. end;
  97. Log(vDebug,SLogRunAction,[AAction,logargs]);
  98. Execute(Args);
  99. finally
  100. Free;
  101. end;
  102. end;
  103. { TPackageHandler }
  104. constructor TPackageHandler.Create(AOwner:TComponent;APackage:TFPPackage);
  105. begin
  106. inherited Create(AOwner);
  107. FCurrentPackage:=APackage;
  108. end;
  109. Function TPackageHandler.ExecuteProcess(Const Prog,Args:String):Integer;
  110. begin
  111. Log(vCommands,SLogExecute,[Prog,Args]);
  112. Result:=SysUtils.ExecuteProcess(Prog,Args);
  113. end;
  114. Procedure TPackageHandler.SetCurrentDir(Const ADir:String);
  115. begin
  116. Log(vCommands,SLogChangeDir,[ADir]);
  117. if not SysUtils.SetCurrentDir(ADir) then
  118. Error(SErrChangeDirFailed,[ADir]);
  119. end;
  120. function TPackageHandler.PackageBuildPath:String;
  121. begin
  122. if CurrentPackage=nil then
  123. Result:='.'
  124. else
  125. Result:=Defaults.BuildDir+CurrentPackage.Name;
  126. end;
  127. function TPackageHandler.PackageRemoteArchive: String;
  128. begin
  129. if not assigned(CurrentPackage) then
  130. Error(SErrNoPackageSpecified);
  131. if CurrentPackage.ExternalURL<>'' then
  132. Result:=CurrentPackage.ExternalURL
  133. else
  134. Result:=Defaults.RemoteRepository+CurrentPackage.FileName;
  135. end;
  136. function TPackageHandler.PackageLocalArchive: String;
  137. begin
  138. if not assigned(CurrentPackage) then
  139. Error(SErrNoPackageSpecified);
  140. Result:=Defaults.PackagesDir+CurrentPackage.FileName;
  141. end;
  142. function TPackageHandler.PackageManifestFile: String;
  143. begin
  144. Result:=DefaultManifestFile;
  145. end;
  146. function TPackageHandler.PackageLogPrefix:String;
  147. begin
  148. if assigned(CurrentPackage) then
  149. Result:='['+CurrentPackage.Name+'] '
  150. else
  151. Result:='[<currentdir>] ';
  152. end;
  153. Procedure TPackageHandler.Log(Level:TVerbosity; Msg:String);
  154. begin
  155. pkgglobals.Log(Level,PackageLogPrefix+Msg);
  156. end;
  157. Procedure TPackageHandler.Log(Level:TVerbosity; Fmt:String; const Args:array of const);
  158. begin
  159. pkgglobals.Log(Level,PackageLogPrefix+Fmt,Args);
  160. end;
  161. Procedure TPackageHandler.Error(Msg:String);
  162. begin
  163. pkgglobals.Error(PackageLogPrefix+Msg);
  164. end;
  165. Procedure TPackageHandler.Error(Fmt:String; const Args:array of const);
  166. begin
  167. pkgglobals.Error(PackageLogPrefix+Fmt,Args);
  168. end;
  169. procedure TPackageHandler.ExecuteAction(APackage: TFPPackage; const AAction: string; const Args: TActionArgs=nil);
  170. begin
  171. pkghandler.ExecuteAction(APackage,AAction,Args);
  172. end;
  173. { TActionStack }
  174. constructor TActionStack.Create;
  175. begin
  176. FList:=TFPList.Create;
  177. end;
  178. destructor TActionStack.Destroy;
  179. begin
  180. FreeAndNil(FList);
  181. end;
  182. procedure TActionStack.Push(APackage:TFPPackage;const AAction:string;const Args:TActionArgs);
  183. var
  184. ActionItem : PActionStackItem;
  185. begin
  186. New(ActionItem);
  187. ActionItem^.ActionPackage:=APackage;
  188. ActionItem^.Action:=AAction;
  189. ActionItem^.Args:=Args;
  190. FList.Add(ActionItem);
  191. end;
  192. procedure TActionStack.Push(APackage:TFPPackage;const AAction:string;const Args:array of string);
  193. var
  194. ActionArgs : TActionArgs;
  195. i : integer;
  196. begin
  197. SetLength(ActionArgs,high(Args)+1);
  198. for i:=low(Args) to high(Args) do
  199. ActionArgs[i]:=Args[i];
  200. Push(APackage,AAction,ActionArgs);
  201. end;
  202. function TActionStack.Pop(out APackage:TFPPackage;out AAction:string;out Args:TActionArgs):boolean;
  203. var
  204. ActionItem : PActionStackItem;
  205. Idx : integer;
  206. begin
  207. Result:=false;
  208. if FList.Count=0 then
  209. exit;
  210. // Retrieve Item from stack
  211. Idx:=FList.Count-1;
  212. ActionItem:=PActionStackItem(FList[Idx]);
  213. FList.Delete(Idx);
  214. // Copy contents and dispose stack item
  215. APackage:=ActionItem^.ActionPackage;
  216. AAction:=ActionItem^.Action;
  217. Args:=ActionItem^.Args;
  218. dispose(ActionItem);
  219. Result:=true;
  220. end;
  221. initialization
  222. PkgHandlerList:=TFPHashList.Create;
  223. finalization
  224. FreeAndNil(PkgHandlerList);
  225. end.