From e5b22557ad651ffda5f347c4325ed8b7e99588e5 Mon Sep 17 00:00:00 2001 From: balazs Date: Sat, 18 Nov 2017 05:24:38 +0000 Subject: [PATCH] Opkman: Preparing OPM for the integration with the build in Package Manager. Step1. git-svn-id: trunk@56430 - --- .gitattributes | 1 + .../onlinepackagemanager.lpk | 6 +- .../onlinepackagemanager.pas | 2 +- .../onlinepackagemanagerintf.pas | 13 +- .../opkman_downloader.pas | 1 + .../onlinepackagemanager/opkman_installer.pas | 149 +++++------------- .../onlinepackagemanager/opkman_intf.pas | 108 +++++++++++++ .../onlinepackagemanager/opkman_mainfrm.pas | 28 ++-- 8 files changed, 175 insertions(+), 133 deletions(-) create mode 100644 components/onlinepackagemanager/opkman_intf.pas diff --git a/.gitattributes b/.gitattributes index a0886a0212..b3ead3351b 100644 --- a/.gitattributes +++ b/.gitattributes @@ -3506,6 +3506,7 @@ components/onlinepackagemanager/opkman_createrepositorypackagefrm.pas svneol=nat components/onlinepackagemanager/opkman_downloader.pas svneol=native#text/pascal components/onlinepackagemanager/opkman_fpcdef.inc svneol=native#text/pascal components/onlinepackagemanager/opkman_installer.pas svneol=native#text/pascal +components/onlinepackagemanager/opkman_intf.pas svneol=native#text/pascal components/onlinepackagemanager/opkman_mainfrm.lfm svneol=native#text/plain components/onlinepackagemanager/opkman_mainfrm.pas svneol=native#text/pascal components/onlinepackagemanager/opkman_options.pas svneol=native#text/pascal diff --git a/components/onlinepackagemanager/onlinepackagemanager.lpk b/components/onlinepackagemanager/onlinepackagemanager.lpk index 9df5de25ef..997773fdd4 100644 --- a/components/onlinepackagemanager/onlinepackagemanager.lpk +++ b/components/onlinepackagemanager/onlinepackagemanager.lpk @@ -20,7 +20,7 @@ - + @@ -123,6 +123,10 @@ + + + + diff --git a/components/onlinepackagemanager/onlinepackagemanager.pas b/components/onlinepackagemanager/onlinepackagemanager.pas index ea5a3e6080..386c150c7e 100644 --- a/components/onlinepackagemanager/onlinepackagemanager.pas +++ b/components/onlinepackagemanager/onlinepackagemanager.pas @@ -15,7 +15,7 @@ uses opkman_createrepositorypackagefrm, opkman_categoriesfrm, opkman_packagedetailsfrm, opkman_updates, opkman_createjsonforupdatesfrm, opkman_uploader, opkman_repositories, opkman_createrepositoryfrm, - opkman_repositorydetailsfrm, opkman_addrepositorypackagefrm, + opkman_repositorydetailsfrm, opkman_addrepositorypackagefrm, opkman_intf, LazarusPackageIntf; implementation diff --git a/components/onlinepackagemanager/onlinepackagemanagerintf.pas b/components/onlinepackagemanager/onlinepackagemanagerintf.pas index 7ff8145ff4..528d5bef59 100644 --- a/components/onlinepackagemanager/onlinepackagemanagerintf.pas +++ b/components/onlinepackagemanager/onlinepackagemanagerintf.pas @@ -27,12 +27,16 @@ unit onlinepackagemanagerintf; interface uses - Classes, MenuIntf, IDECommands, ToolBarIntf, LCLType; + Classes, + // LCL + LCLType, + // IdeIntf + MenuIntf, IDECommands, ToolBarIntf, PackageLinkIntf; procedure Register; implementation -uses opkman_const, opkman_mainfrm; +uses opkman_const, opkman_mainfrm, opkman_intf; procedure IDEMenuSectionClicked(Sender: TObject); begin @@ -62,5 +66,10 @@ begin RegisterIDEMenuCommand(itmPkgGraphSection, 'Online Package Manager', rsLazarusPackageManager, nil, @IDEMenuSectionClicked, IDECommand); end; +initialization + OPMInterface := TOPMInterface.Create; + +finalization + OPMInterface.Free; end. diff --git a/components/onlinepackagemanager/opkman_downloader.pas b/components/onlinepackagemanager/opkman_downloader.pas index 0d7a9076be..7b13944162 100644 --- a/components/onlinepackagemanager/opkman_downloader.pas +++ b/components/onlinepackagemanager/opkman_downloader.pas @@ -261,6 +261,7 @@ begin begin SetLength(JSON, FMS.Size); FMS.Read(Pointer(JSON)^, Length(JSON)); + SerializablePackages.JSONToPackages(JSON); FOnJSONComplete(Self, JSON, FErrTyp, ''); end else diff --git a/components/onlinepackagemanager/opkman_installer.pas b/components/onlinepackagemanager/opkman_installer.pas index d9be34e0ed..8edd3a3f19 100644 --- a/components/onlinepackagemanager/opkman_installer.pas +++ b/components/onlinepackagemanager/opkman_installer.pas @@ -59,7 +59,6 @@ type FTotCnt: Integer; FStarted: Boolean; FInstallStatus: TInstallStatus; - FPackageList: TList; FToInstall: TStringList; FFileName: String; FUnresolvedFileName: String; @@ -71,8 +70,6 @@ type function HasUnresolvedDependency(AName: String): Boolean; function CompilePackage(const AIDEPackage: TIDEPackage; ALazarusPkg: TLazarusPackage): Integer; function InstallPackage: Boolean; - procedure OrderPackagesByDependecy; - procedure PrepareInstallList; procedure DoOnPackageInstallProgress(const AInstallMessage: TInstallMessage; ALazarusPkg: TLazarusPackage); procedure DoOnPackageInstallError(const AInstallMessage: TInstallMessage; ALazarusPkg: TLazarusPackage); procedure Execute; @@ -98,13 +95,11 @@ implementation constructor TPackageInstaller.Create; begin FToInstall := TStringList.Create; - FPackageList := TList.Create; end; destructor TPackageInstaller.Destroy; begin FToInstall.Free; - FPackageList.Free; inherited Destroy; end; @@ -325,136 +320,68 @@ begin FOnPackageInstallCompleted(Self, FNeedToRebuild, FInstallStatus); end; -procedure TPackageInstaller.OrderPackagesByDependecy; +procedure TPackageInstaller.StartInstall; var I, J, K: Integer; - SPos, EPos: Integer; - PackageDependency: TPackageDependency; - PackageDependecyList: TObjectList; + PackageList: TObjectList; LazarusPkg, DependecyPackage: TLazarusPackage; - CanGo: Boolean; + PackageDependency: TPackageDependency; + DependencyFound: Boolean; begin - PackageDependecyList := TObjectList.Create(True); + if FStarted then + Exit; + FStarted := True; + FTotCnt := 0; + PackageList := TObjectList.Create(True); try - FPackageList.Clear; for I := 0 to SerializablePackages.Count - 1 do begin for J := 0 to SerializablePackages.Items[I].LazarusPackages.Count - 1 do begin LazarusPkg := TLazarusPackage(SerializablePackages.Items[I].LazarusPackages.Items[J]); if LazarusPkg.IsInstallable then - FPackageList.Add(LazarusPkg); - end; - end; - repeat - CanGo := True; - for I := FPackageList.Count - 1 downto 1 do - begin - if not CanGo then - Break; - for J := I - 1 downto 0 do begin - LazarusPkg := TLazarusPackage(FPackageList.Items[J]); - PackageDependecyList.Clear; - SerializablePackages.GetPackageDependencies(LazarusPkg.Name, PackageDependecyList, True, True); - if PackageDependecyList.Count > 0 then + SerializablePackages.GetPackageDependencies(LazarusPkg.Name, PackageList, True, True); + if PackageList.Count > 0 then begin - for K := 0 to PackageDependecyList.Count - 1 do + DependencyFound := True; + for K := 0 to PackageList.Count - 1 do begin - PackageDependency := TPackageDependency(PackageDependecyList.Items[K]); + PackageDependency := TPackageDependency(PackageList.Items[K]); DependecyPackage := SerializablePackages.FindLazarusPackage(PackageDependency.PkgFileName + '.lpk'); if DependecyPackage <> nil then begin - if UpperCase(DependecyPackage.Name) = UpperCase(TLazarusPackage(FPackageList.Items[I]).Name) then + if not ((DependecyPackage.PackageState = psInstalled) + and (SerializablePackages.IsInstalledVersionOk(PackageDependency, DependecyPackage.VersionAsString))) then begin - CanGo := False; - SPos := I; - EPos := J; - Break; + if ((DependecyPackage.IsInstallable) + and (SerializablePackages.IsDependencyOk(PackageDependency, DependecyPackage))) then + begin + if not IsPackageInTheList(DependecyPackage.Name) then + FToInstall.Add(DependecyPackage.Name); + end + else + begin + DependencyFound := False; + Break; + end; end; end; - end; - end; - end; - end; - if CanGo = False then - begin - LazarusPkg := TLazarusPackage(FPackageList.Items[SPos]); - FPackageList.Delete(SPos); - FPackageList.Insert(EPos, LazarusPkg); - end; - until CanGo; - finally - PackageDependecyList.Free; - end; -end; - -procedure TPackageInstaller.PrepareInstallList; -var - I, J: Integer; - PackageDependency: TPackageDependency; - PackageDependecyList: TObjectList; - LazarusPkg, DependecyPackage: TLazarusPackage; - DependencyFound: Boolean; -begin - PackageDependecyList := TObjectList.Create(True); - try - for I := 0 to FPackageList.Count - 1 do - begin - LazarusPkg := TLazarusPackage(FPackageList.Items[I]); - if LazarusPkg.IsInstallable then - begin - PackageDependecyList.Clear; - SerializablePackages.GetPackageDependencies(LazarusPkg.Name, PackageDependecyList, True, True); - if PackageDependecyList.Count > 0 then - begin - DependencyFound := True; - for J := 0 to PackageDependecyList.Count - 1 do - begin - PackageDependency := TPackageDependency(PackageDependecyList.Items[J]); - DependecyPackage := SerializablePackages.FindLazarusPackage(PackageDependency.PkgFileName + '.lpk'); - if DependecyPackage <> nil then - begin - if not ((DependecyPackage.PackageState = psInstalled) - and (SerializablePackages.IsInstalledVersionOk(PackageDependency, DependecyPackage.VersionAsString))) then - begin - if ((DependecyPackage.IsInstallable) - and (SerializablePackages.IsDependencyOk(PackageDependency, DependecyPackage))) then - begin - if not IsPackageInTheList(DependecyPackage.Name) then - FToInstall.Add(DependecyPackage.Name); - end - else - begin - DependencyFound := False; - Break; - end; - end; - end; + end; + if (not DependencyFound) then + begin + if (not IsPackageInTheList(LazarusPkg.Name)) then + FToInstall.Add(LazarusPkg.Name + ' ' + DependecyPackage.Name) + end end; - if (not DependencyFound) then - begin - if (not IsPackageInTheList(LazarusPkg.Name)) then - FToInstall.Add(LazarusPkg.Name + ' ' + DependecyPackage.Name) - end - end; - if (not IsPackageInTheList(LazarusPkg.Name)) then - FToInstall.Add(LazarusPkg.Name); + if (not IsPackageInTheList(LazarusPkg.Name)) then + FToInstall.Add(LazarusPkg.Name); + end; end; end; finally - PackageDependecyList.Free; - end -end; - -procedure TPackageInstaller.StartInstall; -begin - if FStarted then - Exit; - FStarted := True; - FTotCnt := 0; - OrderPackagesByDependecy; - PrepareInstallList; + PackageList.Free; + end; FTotCnt := FToInstall.Count; Execute; end; diff --git a/components/onlinepackagemanager/opkman_intf.pas b/components/onlinepackagemanager/opkman_intf.pas new file mode 100644 index 0000000000..63243ca0ff --- /dev/null +++ b/components/onlinepackagemanager/opkman_intf.pas @@ -0,0 +1,108 @@ +{ + *************************************************************************** + * * + * This source is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This code is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * General Public License for more details. * + * * + * A copy of the GNU General Public License is available on the World * + * Wide Web at . You can also * + * obtain it by writing to the Free Software Foundation, * + * Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1335, USA. * + * * + *************************************************************************** + + Author: Balázs Székely + Abstract: + This unit allows OPM to interact with the Lazarus package system} + +unit opkman_intf; + +{$mode objfpc}{$H+} + +interface + +uses + Classes, SysUtils, contnrs, fpjson, + // IdeIntf + LazIDEIntf, PackageIntf, PackageLinkIntf, PackageDependencyIntf, + // OPM + opkman_timer, opkman_downloader; + +type + + { TOPMMain } + + //just a dummy class for now, it must be inherited from ideintf(packagelinkintf.pas) + //it will allow the communication between OPM and the IDE + TOPMInterface = class + private + FWaitForIDE: TThreadTimer; + procedure DoWaitForIDE(Sender: TObject); + procedure InitOPM; + public + constructor Create; + destructor Destroy; override; + public + end; + +var + OPMInterface: TOPMInterface; + +implementation + +uses opkman_serializablepackages, opkman_common, opkman_options; + +{ TOPMMain } + +constructor TOPMInterface.Create; +begin + FWaitForIDE := TThreadTimer.Create; + FWaitForIDE.Interval := 100; + FWaitForIDE.OnTimer := @DoWaitForIDE; + FWaitForIDE.StartTimer; +end; + +procedure TOPMInterface.DoWaitForIDE(Sender: TObject); +begin + if Assigned(LazarusIDE) and Assigned(PackageEditingInterface) then + begin + InitOPM; + FWaitForIDE.StopTimer; + FWaitForIDE.Terminate; + FWaitForIDE := nil; + end; +end; + +procedure TOPMInterface.InitOPM; +begin + InitLocalRepository; + Options := TOptions.Create(LocalRepositoryConfigFile); + SerializablePackages := TSerializablePackages.Create; + PackageDownloader := TPackageDownloader.Create(Options.RemoteRepository[Options.ActiveRepositoryIndex]); + InstallPackageList := TObjectList.Create(True); + PackageDownloader.DownloadJSON(Options.ConTimeOut*1000); +end; + +destructor TOPMInterface.Destroy; +begin + if Assigned(FWaitForIDE) then + begin + FWaitForIDE.StopTimer; + FWaitForIDE.Terminate; + end; + PackageDownloader.Free; + SerializablePackages.Free; + Options.Free; + InstallPackageList.Free; + inherited Destroy; +end; + +end. + diff --git a/components/onlinepackagemanager/opkman_mainfrm.pas b/components/onlinepackagemanager/opkman_mainfrm.pas index 111927db70..ab44038e93 100644 --- a/components/onlinepackagemanager/opkman_mainfrm.pas +++ b/components/onlinepackagemanager/opkman_mainfrm.pas @@ -178,18 +178,13 @@ implementation procedure TMainFrm.FormCreate(Sender: TObject); begin - InitLocalRepository; - Options := TOptions.Create(LocalRepositoryConfigFile); VisualTree := TVisualTree.Create(pnMain, imTree, pmTree); VisualTree.OnChecking := @DoOnChecking; VisualTree.OnChecked := @DoOnChecked; - SerializablePackages := TSerializablePackages.Create; SerializablePackages.OnProcessJSON := @DoOnProcessJSON; - PackageDownloader := TPackageDownloader.Create(Options.RemoteRepository[Options.ActiveRepositoryIndex]); PackageDownloader.OnJSONProgress := @DoOnJSONProgress; PackageDownloader.OnJSONDownloadCompleted := @DoOnJSONDownloadCompleted; StartUpdates; - InstallPackageList := TObjectList.Create(True); FHintTimeOut := Application.HintHidePause; Application.HintHidePause := 1000000; {$IF LCL_FULLVERSION >= 1070000} @@ -220,12 +215,11 @@ end; procedure TMainFrm.FormDestroy(Sender: TObject); begin + SerializablePackages.OnProcessJSON := nil; + PackageDownloader.OnJSONProgress := nil; + PackageDownloader.OnJSONDownloadCompleted := nil; StopUpdates; - PackageDownloader.Free; - SerializablePackages.Free; VisualTree.Free; - Options.Free; - InstallPackageList.Free; Application.HintHidePause := FHintTimeOut; end; @@ -255,9 +249,6 @@ begin begin SetupMessage(rsMainFrm_rsMessageChangingRepository); Sleep(1500); - StopUpdates; - SerializablePackages.Clear; - StartUpdates; end else Updates.PauseUpdate; @@ -365,7 +356,7 @@ begin etNone: begin SetupMessage(rsMainFrm_rsMessageParsingJSON); - if (not SerializablePackages.JSONToPackages(AJSON)) or (SerializablePackages.Count = 0) then + if (SerializablePackages.Count = 0) then begin EnableDisableControls(True); SetupMessage(rsMainFrm_rsMessageNoPackage); @@ -399,6 +390,12 @@ begin end; end; +procedure TMainFrm.DoOnJSONProgress(Sender: TObject); +begin + Application.ProcessMessages; +end; + + procedure TMainFrm.DoOnProcessJSON(Sender: TObject); begin Application.ProcessMessages; @@ -506,11 +503,6 @@ begin EnableDisableControls(True); end; -procedure TMainFrm.DoOnJSONProgress(Sender: TObject); -begin - Application.ProcessMessages; -end; - procedure TMainFrm.cbAllClick(Sender: TObject); begin VisualTree.CheckNodes(cbAll.Checked);