pkgpackagesstructure.pp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441
  1. {
  2. This file is part of the fppkg package manager
  3. Copyright (c) 1999-2022 by the Free Pascal development team
  4. See the file COPYING.FPC, included in this distribution,
  5. for details about the copyright.
  6. This program is distributed in the hope that it will be useful,
  7. but WITHOUT ANY WARRANTY; without even the implied warranty of
  8. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  9. **********************************************************************}
  10. {$IFNDEF FPC_DOTTEDUNITS}
  11. unit pkgPackagesStructure;
  12. {$ENDIF FPC_DOTTEDUNITS}
  13. {$mode objfpc}{$H+}
  14. interface
  15. {$IFDEF FPC_DOTTEDUNITS}
  16. uses
  17. System.Classes,
  18. System.SysUtils,
  19. FpPkg.Repos,
  20. FpPkg.XmlRep,
  21. FpPkg.Options;
  22. {$ELSE FPC_DOTTEDUNITS}
  23. uses
  24. Classes,
  25. SysUtils,
  26. fprepos,
  27. fpxmlrep,
  28. pkgoptions;
  29. {$ENDIF FPC_DOTTEDUNITS}
  30. type
  31. { TFPRemotePackagesStructure }
  32. TFPRemotePackagesStructure = class(TFPCustomPackagesStructure)
  33. public
  34. class function GetRepositoryOptionSectionClass: TFppkgRepositoryOptionSectionClass; override;
  35. function UnzipBeforeUse: Boolean; override;
  36. function AddPackagesToRepository(ARepository: TFPRepository): Boolean; override;
  37. end;
  38. { TFPCustomFileSystemPackagesStructure }
  39. TFPCustomFileSystemPackagesStructure = class(TFPCustomPackagesStructure)
  40. private
  41. FPath: string;
  42. protected
  43. function GetPath: string; virtual;
  44. procedure SetPath(AValue: string); virtual;
  45. procedure AddPackageToRepository(ARepository: TFPRepository; APackageName: string; APackageFilename: string);
  46. public
  47. property Path: string read GetPath write SetPath;
  48. end;
  49. { TFPInstalledPackagesStructure }
  50. TFPInstalledPackagesStructure = class(TFPCustomFileSystemPackagesStructure)
  51. private
  52. FPrefix: string;
  53. public
  54. class function GetRepositoryOptionSectionClass: TFppkgRepositoryOptionSectionClass; override;
  55. procedure InitializeWithOptions(ARepoOptionSection: TFppkgRepositoryOptionSection; AnOptions: TFppkgOptions; ACompilerOptions: TCompilerOptions); override;
  56. function AddPackagesToRepository(ARepository: TFPRepository): Boolean; override;
  57. function GetUnitDirectory(APackage: TFPPackage): string; override;
  58. function GetPrefix: string; override;
  59. function GetBaseInstallDir: string; override;
  60. // The prefix is used on installing packages
  61. property Prefix: string read FPrefix write FPrefix;
  62. end;
  63. { TFPCurrentDirectoryPackagesStructure }
  64. TFPCurrentDirectoryPackagesStructure = class(TFPCustomFileSystemPackagesStructure)
  65. protected
  66. procedure SetPath(AValue: string); override;
  67. public
  68. function AddPackagesToRepository(ARepository: TFPRepository): Boolean; override;
  69. function GetBuildPathDirectory(APackage: TFPPackage): string; override;
  70. end;
  71. { TFPArchiveFilenamePackagesStructure }
  72. TFPArchiveFilenamePackagesStructure = class(TFPCustomPackagesStructure)
  73. private
  74. FArchiveFileName: string;
  75. public
  76. function AddPackagesToRepository(ARepository: TFPRepository): Boolean; override;
  77. function UnzipBeforeUse: Boolean; override;
  78. property ArchiveFileName: string read FArchiveFileName write FArchiveFileName;
  79. end;
  80. { TFPOriginalSourcePackagesStructure }
  81. TFPOriginalSourcePackagesStructure = class(TFPCustomPackagesStructure)
  82. private
  83. FOriginalRepository: TFPRepository;
  84. public
  85. constructor Create(AOwner: TComponent; OriginalRepository: TFPRepository);
  86. function AddPackagesToRepository(ARepository: TFPRepository): Boolean; override;
  87. function GetBuildPathDirectory(APackage: TFPPackage): string; override;
  88. end;
  89. { TFPTemporaryDirectoryPackagesStructure }
  90. TFPTemporaryDirectoryPackagesStructure = class(TFPCustomFileSystemPackagesStructure)
  91. private
  92. FPackage: TFPPackage;
  93. function GetTempPackageName: string;
  94. procedure SetTempPackageName(AValue: string);
  95. public
  96. function AddPackagesToRepository(ARepository: TFPRepository): Boolean; override;
  97. function GetBuildPathDirectory(APackage: TFPPackage): string; override;
  98. procedure SetTempPath(APath: string);
  99. property TempPackageName: string read GetTempPackageName write SetTempPackageName;
  100. end;
  101. implementation
  102. {$IFDEF FPC_DOTTEDUNITS}
  103. uses
  104. Fpmkunit,
  105. FpPkg.Messages,
  106. FpPkg.PackageRepos,
  107. FpPkg.Globals;
  108. {$ELSE FPC_DOTTEDUNITS}
  109. uses
  110. fpmkunit,
  111. pkgmessages,
  112. pkgrepos,
  113. pkgglobals;
  114. {$ENDIF FPC_DOTTEDUNITS}
  115. { TFPArchiveFilenamePackagesStructure }
  116. function TFPArchiveFilenamePackagesStructure.AddPackagesToRepository(ARepository: TFPRepository): Boolean;
  117. var
  118. Package: TFPPackage;
  119. begin
  120. Result := True;
  121. Package := ARepository.AddPackage(CmdLinePackageName);
  122. Package.LocalFileName := FArchiveFileName;
  123. Package.PackagesStructure := Self;
  124. end;
  125. function TFPArchiveFilenamePackagesStructure.UnzipBeforeUse: Boolean;
  126. begin
  127. Result := True;
  128. end;
  129. { TFPCustomFileSystemPackagesStructure }
  130. function TFPCustomFileSystemPackagesStructure.GetPath: string;
  131. begin
  132. Result := FPath;
  133. end;
  134. procedure TFPCustomFileSystemPackagesStructure.SetPath(AValue: string);
  135. begin
  136. FPath := AValue;
  137. end;
  138. procedure TFPCustomFileSystemPackagesStructure.AddPackageToRepository(ARepository: TFPRepository; APackageName: string; APackageFilename: string);
  139. var
  140. P: TFPPackage;
  141. begin
  142. P:=ARepository.AddPackage(APackageName);
  143. try
  144. P.LoadUnitConfigFromFile(APackageFilename);
  145. P.PackagesStructure:=Self;
  146. log(llDebug,SLogFoundPackageInFile,[P.Name, APackageFilename]);
  147. if P.IsFPMakeAddIn then
  148. AddFPMakeAddIn(P);
  149. except
  150. on E: Exception do
  151. begin
  152. log(llWarning,SLogFailedLoadingPackage,[APackageName, APackageFilename, E.Message]);
  153. P.Free;
  154. end;
  155. end;
  156. end;
  157. { TFPTemporaryDirectoryPackagesStructure }
  158. function TFPTemporaryDirectoryPackagesStructure.GetTempPackageName: string;
  159. begin
  160. Result := FPackage.Name;
  161. end;
  162. procedure TFPTemporaryDirectoryPackagesStructure.SetTempPackageName(AValue: string);
  163. begin
  164. FPackage.Name := AValue;
  165. end;
  166. function TFPTemporaryDirectoryPackagesStructure.AddPackagesToRepository(ARepository: TFPRepository): Boolean;
  167. begin
  168. Result := True;
  169. FPackage := ARepository.AddPackage('');
  170. FPackage.PackagesStructure := Self;
  171. end;
  172. function TFPTemporaryDirectoryPackagesStructure.GetBuildPathDirectory(APackage: TFPPackage): string;
  173. begin
  174. Result := FPath;
  175. end;
  176. procedure TFPTemporaryDirectoryPackagesStructure.SetTempPath(APath: string);
  177. begin
  178. FPath := APath;
  179. end;
  180. { TFPOriginalSourcePackagesStructure }
  181. constructor TFPOriginalSourcePackagesStructure.Create(AOwner: TComponent;
  182. OriginalRepository: TFPRepository);
  183. begin
  184. inherited Create(Owner);
  185. FOriginalRepository := OriginalRepository;
  186. end;
  187. function TFPOriginalSourcePackagesStructure.AddPackagesToRepository(
  188. ARepository: TFPRepository): Boolean;
  189. var
  190. i: Integer;
  191. OrgPackage: TFPPackage;
  192. P: TFPPackage;
  193. begin
  194. Result := True;
  195. for i := 0 to FOriginalRepository.PackageCount -1 do
  196. begin
  197. OrgPackage := FOriginalRepository.Packages[i];
  198. if (OrgPackage.SourcePath<>'') and DirectoryExists(OrgPackage.SourcePath) then
  199. begin
  200. P:=ARepository.AddPackage(OrgPackage.Name);
  201. P.PackagesStructure:=Self;
  202. P.Assign(OrgPackage);
  203. end;
  204. end;
  205. end;
  206. function TFPOriginalSourcePackagesStructure.GetBuildPathDirectory(
  207. APackage: TFPPackage): string;
  208. begin
  209. Result:=APackage.SourcePath;
  210. end;
  211. { TFPCurrentDirectoryPackagesStructure }
  212. procedure TFPCurrentDirectoryPackagesStructure.SetPath(AValue: string);
  213. begin
  214. if AValue = '' then
  215. AValue := GetCurrentDir;
  216. inherited SetPath(AValue);
  217. end;
  218. function TFPCurrentDirectoryPackagesStructure.AddPackagesToRepository(
  219. ARepository: TFPRepository): Boolean;
  220. var
  221. Package: TFPPackage;
  222. begin
  223. Result := True;
  224. Package := ARepository.AddPackage(CurrentDirPackageName);
  225. Package.PackagesStructure := Self;
  226. end;
  227. function TFPCurrentDirectoryPackagesStructure.GetBuildPathDirectory(APackage: TFPPackage): string;
  228. begin
  229. Result := FPath;
  230. end;
  231. { TFPRemotePackagesStructure }
  232. class function TFPRemotePackagesStructure.GetRepositoryOptionSectionClass: TFppkgRepositoryOptionSectionClass;
  233. begin
  234. Result := nil;
  235. end;
  236. function TFPRemotePackagesStructure.UnzipBeforeUse: Boolean;
  237. begin
  238. Result := True;
  239. end;
  240. function TFPRemotePackagesStructure.AddPackagesToRepository(ARepository: TFPRepository): Boolean;
  241. var
  242. S : String;
  243. X : TFPXMLRepositoryHandler;
  244. i: Integer;
  245. begin
  246. Result := True;
  247. // Repository
  248. S:=FOptions.GlobalSection.LocalPackagesFile;
  249. log(llDebug,SLogLoadingPackagesFile,[S]);
  250. if not FileExists(S) then
  251. exit;
  252. try
  253. X:=TFPXMLRepositoryHandler.Create;
  254. With X do
  255. try
  256. LoadFromXml(ARepository,S);
  257. finally
  258. Free;
  259. end;
  260. for i := 0 to ARepository.PackageCount -1 do
  261. ARepository.Packages[i].PackagesStructure := Self;
  262. except
  263. on E : Exception do
  264. begin
  265. Log(llError,E.Message);
  266. Error(SErrCorruptPackagesFile,[S]);
  267. end;
  268. end;
  269. end;
  270. { TFPInstalledPackagesStructure }
  271. class function TFPInstalledPackagesStructure.GetRepositoryOptionSectionClass: TFppkgRepositoryOptionSectionClass;
  272. begin
  273. Result := TFppkgRepositoryOptionSection;
  274. end;
  275. procedure TFPInstalledPackagesStructure.InitializeWithOptions(
  276. ARepoOptionSection: TFppkgRepositoryOptionSection; AnOptions: TFppkgOptions;
  277. ACompilerOptions: TCompilerOptions);
  278. var
  279. RepoOptSection: TFppkgRepositoryOptionSection;
  280. begin
  281. inherited InitializeWithOptions(ARepoOptionSection, AnOptions, ACompilerOptions);
  282. RepoOptSection := ARepoOptionSection as TFppkgRepositoryOptionSection;
  283. Prefix := RepoOptSection.Prefix;
  284. InstallRepositoryName := RepoOptSection.InstallRepositoryName;
  285. Path := RepoOptSection.Path;
  286. end;
  287. function TFPInstalledPackagesStructure.AddPackagesToRepository(ARepository: TFPRepository): Boolean;
  288. procedure LoadPackagefpcFromFile(APackage:TFPPackage;const AFileName: String);
  289. Var
  290. L : TStrings;
  291. V : String;
  292. begin
  293. L:=TStringList.Create;
  294. Try
  295. ReadIniFile(AFileName,L);
  296. V:=L.Values['version'];
  297. APackage.Version.AsString:=V;
  298. Finally
  299. L.Free;
  300. end;
  301. end;
  302. var
  303. SR : TSearchRec;
  304. P : TFPPackage;
  305. UF,UD : String;
  306. FpmkDir : String;
  307. UnitDir: String;
  308. begin
  309. Result:=false;
  310. FpmkDir:=IncludeTrailingPathDelimiter(FPath)+'fpmkinst'+PathDelim+FCompilerOptions.CompilerTarget+PathDelim;
  311. DirectoryExistsLog(FpmkDir);
  312. if FindFirst(IncludeTrailingPathDelimiter(FpmkDir)+'*'+FpmkExt,faDirectory,SR)=0 then
  313. begin
  314. log(llDebug,SLogFindInstalledPackages,[FpmkDir]);
  315. repeat
  316. if ((SR.Attr and faDirectory)=0) then
  317. begin
  318. // Try new .fpm-file
  319. AddPackageToRepository(ARepository, ChangeFileExt(SR.Name,''), FpmkDir+SR.Name);
  320. end;
  321. until FindNext(SR)<>0;
  322. end;
  323. FindClose(SR);
  324. // Search for non-fpmkunit packages
  325. UnitDir:=IncludeTrailingPathDelimiter(FPath)+'units'+PathDelim+FCompilerOptions.CompilerTarget+PathDelim;
  326. DirectoryExistsLog(UnitDir);
  327. if FindFirst(IncludeTrailingPathDelimiter(UnitDir)+AllFiles,faDirectory,SR)=0 then
  328. begin
  329. log(llDebug,SLogFindInstalledPackages,[UnitDir]);
  330. repeat
  331. if ((SR.Attr and faDirectory)=faDirectory) and (SR.Name<>'.') and (SR.Name<>'..') then
  332. begin
  333. UD:=IncludeTrailingPathDelimiter(IncludeTrailingPathDelimiter(UnitDir)+SR.Name);
  334. // Try new fpunits.cfg
  335. UF:=UD+UnitConfigFileName;
  336. if FileExists(UF) then
  337. begin
  338. if not Assigned(ARepository.FindPackage(SR.Name)) then
  339. begin
  340. AddPackageToRepository(ARepository, SR.Name, UF);
  341. end;
  342. end
  343. else
  344. begin
  345. // Try Old style Package.fpc
  346. UF:=UD+'Package.fpc';
  347. if FileExists(UF) then
  348. begin
  349. if not Assigned(ARepository.FindPackage(SR.Name)) then
  350. begin
  351. P:=ARepository.AddPackage(SR.Name);
  352. P.PackagesStructure:=Self;
  353. LoadPackagefpcFromFile(P,UF);
  354. log(llDebug,SLogFoundPackageInFile,[P.Name, UF]);
  355. end;
  356. end;
  357. end;
  358. end;
  359. until FindNext(SR)<>0;
  360. end;
  361. FindClose(SR);
  362. Result:=true;
  363. end;
  364. function TFPInstalledPackagesStructure.GetUnitDirectory(APackage: TFPPackage): string;
  365. begin
  366. Result:=IncludeTrailingPathDelimiter(FPath)+'units'+PathDelim+FCompilerOptions.CompilerTarget+PathDelim+APackage.Name+PathDelim;
  367. end;
  368. function TFPInstalledPackagesStructure.GetPrefix: string;
  369. begin
  370. Result:=IncludeTrailingPathDelimiter(FPrefix);
  371. end;
  372. function TFPInstalledPackagesStructure.GetBaseInstallDir: string;
  373. begin
  374. Result:=FPath;
  375. end;
  376. initialization
  377. TFPCustomPackagesStructure.RegisterPackagesStructureClass(TFPRemotePackagesStructure);
  378. TFPCustomPackagesStructure.RegisterPackagesStructureClass(TFPInstalledPackagesStructure);
  379. end.