unit pkgUninstalledSrcsRepo; {$mode objfpc}{$H+} interface uses Classes, SysUtils, fpmkunit, pkgoptions, pkgFppkg, pkgglobals, pkgmessages, fprepos, pkgrepos, pkghandler, pkgPackagesStructure; type { TFppkgUninstalledSourceRepositoryOptionSection } TFppkgUninstalledSourceRepositoryOptionSection = class(TFppkgRepositoryOptionSection) protected class function GetKey: string; override; public function GetRepositoryType: TFPRepositoryType; override; end; { TFPUninstalledSourcesAvailablePackagesStructure } TFPUninstalledSourcesAvailablePackagesStructure = class(TFPCustomFileSystemPackagesStructure) public class function GetRepositoryOptionSectionClass: TFppkgRepositoryOptionSectionClass; override; procedure InitializeWithOptions(ARepoOptionSection: TFppkgRepositoryOptionSection; AnOptions: TFppkgOptions; ACompilerOptions: TCompilerOptions); override; function AddPackagesToRepository(ARepository: TFPRepository): Boolean; override; function GetBuildPathDirectory(APackage: TFPPackage): string; override; end; { TFppkgUninstalledRepositoryOptionSection } TFppkgUninstalledRepositoryOptionSection = class(TFppkgRepositoryOptionSection) private FSourceRepositoryName: string; protected class function GetKey: string; override; public procedure AddKeyValue(const AKey, AValue: string); override; procedure LogValues(ALogLevel: TLogLevel); override; function GetRepositoryType: TFPRepositoryType; override; procedure SaveToStrings(AStrings: TStrings); override; property SourceRepositoryName: string read FSourceRepositoryName write FSourceRepositoryName; end; { TFPUninstalledSourcesPackagesStructure } TFPUninstalledSourcesPackagesStructure = class(TFPCustomFileSystemPackagesStructure) private FSourceRepositoryName: string; FLinkedRepositoryName: string; public class function GetRepositoryOptionSectionClass: TFppkgRepositoryOptionSectionClass; override; procedure InitializeWithOptions(ARepoOptionSection: TFppkgRepositoryOptionSection; AnOptions: TFppkgOptions; ACompilerOptions: TCompilerOptions); override; function AddPackagesToRepository(ARepository: TFPRepository): Boolean; override; function IsInstallationNeeded(APackage: TFPPackage): TFPInstallationNeeded; override; function GetBaseInstallDir: string; override; function GetConfigFileForPackage(APackage: TFPPackage): string; override; property SourceRepositoryName: string read FSourceRepositoryName write FSourceRepositoryName; end; implementation const KeySourceRepository = 'SourceRepository'; SLogSourceRepository = ' SourceRepository:%s'; KeySrcRepositorySection = 'UninstalledSourceRepository'; KeyUninstalledRepository = 'UninstalledRepository'; KeyRepositorySection = 'Repository'; { TFPUninstalledSourcesPackagesStructure } class function TFPUninstalledSourcesPackagesStructure.GetRepositoryOptionSectionClass: TFppkgRepositoryOptionSectionClass; begin Result := TFppkgUninstalledRepositoryOptionSection; end; procedure TFPUninstalledSourcesPackagesStructure.InitializeWithOptions( ARepoOptionSection: TFppkgRepositoryOptionSection; AnOptions: TFppkgOptions; ACompilerOptions: TCompilerOptions); var RepoOptionSection: TFppkgUninstalledRepositoryOptionSection; begin inherited InitializeWithOptions(ARepoOptionSection, AnOptions, ACompilerOptions); RepoOptionSection := ARepoOptionSection as TFppkgUninstalledRepositoryOptionSection; path := RepoOptionSection.Path; SourceRepositoryName := RepoOptionSection.SourceRepositoryName; FLinkedRepositoryName := RepoOptionSection.RepositoryName; end; function TFPUninstalledSourcesPackagesStructure.AddPackagesToRepository(ARepository: TFPRepository): Boolean; var SRD : TSearchRec; SRF : TSearchRec; P : TFPPackage; UD : String; begin Result:=false; log(llDebug,SLogFindInstalledPackages,[Path]); if FindFirst(Path+AllFiles,faDirectory,SRD)=0 then begin repeat // Try new .fpm-file UD:=Path+SRD.Name+PathDelim; if FindFirst(UD+'*'+FpmkExt,faAnyFile,SRF)=0 then begin repeat AddPackageToRepository(ARepository, ChangeFileExt(SRF.Name,''), UD+SRF.Name); until FindNext(SRF)<>0; end; FindClose(SRF); until FindNext(SRD)<>0; end; FindClose(SRD); Result:=true; end; function TFPUninstalledSourcesPackagesStructure.IsInstallationNeeded(APackage: TFPPackage): TFPInstallationNeeded; begin if (APackage.Repository.RepositoryName=SourceRepositoryName) or (Assigned(APackage.Repository.DefaultPackagesStructure) and (APackage.Repository.DefaultPackagesStructure.InstallRepositoryName=FLinkedRepositoryName)) then Result := fpinNoInstallationNeeded else Result := fpinInstallationImpossible; end; function TFPUninstalledSourcesPackagesStructure.GetBaseInstallDir: string; begin Result := Path; end; function TFPUninstalledSourcesPackagesStructure.GetConfigFileForPackage(APackage: TFPPackage): string; begin if APackage.SourcePath<>'' then Result := IncludeTrailingPathDelimiter(APackage.SourcePath) else Result := IncludeTrailingPathDelimiter(GetBaseInstallDir)+APackage.Name+PathDelim; Result := Result +APackage.Name+'-'+FCompilerOptions.CompilerTarget+FpmkExt; end; { TFppkgUninstalledRepositoryOptionSection } class function TFppkgUninstalledRepositoryOptionSection.GetKey: string; begin Result := KeyUninstalledRepository; end; procedure TFppkgUninstalledRepositoryOptionSection.AddKeyValue(const AKey, AValue: string); begin if SameText(AKey,KeySourceRepository) then SourceRepositoryName := AValue else inherited AddKeyValue(AKey, AValue); end; procedure TFppkgUninstalledRepositoryOptionSection.LogValues(ALogLevel: TLogLevel); begin inherited LogValues(ALogLevel); log(ALogLevel,SLogSourceRepository,[FSourceRepositoryName]); end; function TFppkgUninstalledRepositoryOptionSection.GetRepositoryType: TFPRepositoryType; begin Result := fprtInstalled; end; procedure TFppkgUninstalledRepositoryOptionSection.SaveToStrings(AStrings: TStrings); begin inherited SaveToStrings(AStrings); if SourceRepositoryName<>'' then AStrings.Add(KeySourceRepository+'='+SourceRepositoryName); end; { TFppkgUninstalledSourceRepositoryOptionSection } class function TFppkgUninstalledSourceRepositoryOptionSection.GetKey: string; begin Result := KeySrcRepositorySection; end; function TFppkgUninstalledSourceRepositoryOptionSection.GetRepositoryType: TFPRepositoryType; begin Result := fprtAvailable; end; { TFPUninstalledSourcesPackagesStructure } class function TFPUninstalledSourcesAvailablePackagesStructure.GetRepositoryOptionSectionClass: TFppkgRepositoryOptionSectionClass; begin Result := TFppkgUninstalledSourceRepositoryOptionSection; end; procedure TFPUninstalledSourcesAvailablePackagesStructure.InitializeWithOptions( ARepoOptionSection: TFppkgRepositoryOptionSection; AnOptions: TFppkgOptions; ACompilerOptions: TCompilerOptions); begin inherited InitializeWithOptions(ARepoOptionSection, AnOptions, ACompilerOptions); path := TFppkgUninstalledSourceRepositoryOptionSection(ARepoOptionSection).Path; end; function TFPUninstalledSourcesAvailablePackagesStructure.AddPackagesToRepository(ARepository: TFPRepository): Boolean; var SR : TSearchRec; AManifestFile, AFPMakeFile: String; i: Integer; TempPackagesStructure: TFPTemporaryDirectoryPackagesStructure; TempRepo: TFPRepository; PackageName: string; PackageManager: TpkgFppkg; begin Result:=false; TempPackagesStructure := TFPTemporaryDirectoryPackagesStructure.Create(Owner); TempPackagesStructure.InitializeWithOptions(nil, FOptions, FCompilerOptions); TempRepo := TFPRepository.Create(Owner); TempRepo.RepositoryName := 'TempScanUninstPackages'; TempRepo.Description := 'Temp list of packages during scanning of source-packages'; TempRepo.RepositoryType := fprtAvailable; TempRepo.DefaultPackagesStructure := TempPackagesStructure; TempPackagesStructure.AddPackagesToRepository(TempRepo); if Owner is TPkgFppkg then PackageManager := TPkgfppkg(owner) else PackageManager := GFPpkg; if Assigned(PackageManager) then PackageManager.RepositoryList.Add(TempRepo); try log(llDebug,SLogFindInstalledPackages,[Path]); if FindFirst(Path+AllFiles,faDirectory,SR)=0 then begin repeat if ((SR.Attr and faDirectory)=faDirectory) and (SR.Name<>'.') and (SR.Name<>'..') then begin AFPMakeFile := Path+SR.Name+PathDelim+FPMakePPFile; if FileExistsLog(AFPMakeFile) then begin AManifestFile := Path+SR.Name+PathDelim+ManifestFile; if not FileExists(AManifestFile) or (FileAge(AManifestFile) < FileAge(AFPMakeFile)) then begin // (Re-)create manifest if assigned(PackageManager) then begin try TempPackagesStructure.SetTempPath(Path+SR.Name); PackageName := SR.Name + '_create_manifest'; TempPackagesStructure.TempPackageName := PackageName; pkghandler.ExecuteAction(PackageName,'fpmakemanifest',PackageManager); except on E: Exception do begin log(llWarning, SLogFailedToCreateManifest ,[AFPMakeFile, E.Message]); Continue; end; end; end else begin log(llError, SLogFailedToCreateManifest ,[AFPMakeFile, 'No packagemanager available']); end; end; ARepository.AddPackagesFromManifestFile(AManifestFile); for i := 0 to ARepository.PackageCount -1 do if ARepository.Packages[i].SourcePath = '' then ARepository.Packages[i].SourcePath := SR.Name; end end; until FindNext(SR)<>0; end; FindClose(SR); finally if Assigned(PackageManager) then PackageManager.RepositoryList.Remove(TempRepo); TempRepo.Free; TempPackagesStructure.Free; end; for i := 0 to ARepository.PackageCount -1 do ARepository.Packages[i].PackagesStructure := Self; Result:=true; end; function TFPUninstalledSourcesAvailablePackagesStructure.GetBuildPathDirectory(APackage: TFPPackage): string; begin if APackage.SourcePath<>'' then Result := Path+APackage.SourcePath else Result := Path+APackage.Name end; initialization TFPCustomPackagesStructure.RegisterPackagesStructureClass(TFPUninstalledSourcesAvailablePackagesStructure); TFPCustomPackagesStructure.RegisterPackagesStructureClass(TFPUninstalledSourcesPackagesStructure); end.