Browse Source

* Re-structured handling of broken packages. Packages are now evaluated per
repository. If a package is broken depends on which repositories are
taken into account.

git-svn-id: trunk@34742 -

joost 8 years ago
parent
commit
f9e7600fe3

+ 87 - 3
packages/fppkg/src/fprepos.pp

@@ -89,7 +89,6 @@ type
     FEmail: String;
     FFPMakeOptionsString: string;
     FKeywords: String;
-    FRecompileBroken: boolean;
     FSourcePath: string;
     FIsFPMakeAddIn: boolean;
     FLicense: String;
@@ -108,6 +107,7 @@ type
     FLocalFileName : String;
     FPackagesStructure: TFPCustomPackagesStructure;
     function GetFileName: String;
+    function GetRepository: TFPRepository;
     procedure SetName(const AValue: String);
     procedure SetUnusedVersion(const AValue: TFPVersion);
     procedure SetVersion(const AValue: TFPVersion);
@@ -121,10 +121,11 @@ type
     procedure LoadUnitConfigFromFile(Const AFileName: String);
     Procedure Assign(Source : TPersistent); override;
     Function AddDependency(Const APackageName : String; const AMinVersion : String = '') : TFPDependency;
+    Function IsPackageBroken: Boolean;
     Property Dependencies : TFPDependencies Read FDependencies;
-    Property RecompileBroken : boolean read FRecompileBroken write FRecompileBroken;
     Property OSes : TOSes Read FOSes Write FOses;
     Property CPUs : TCPUs Read FCPUs Write FCPUs;
+    Property Repository: TFPRepository read GetRepository;
   Published
     Property Name : String Read FName Write SetName;
     Property Author : String Read FAuthor Write FAuthor;
@@ -152,9 +153,11 @@ type
 
   TFPPackages = Class(TStreamCollection)
   private
+    FRepository: TFPRepository;
     FVersion : Integer;
     function GetPackage(Index : Integer): TFPPackage;
     procedure SetPackage(Index : Integer; const AValue: TFPPackage);
+    procedure SetRepository(AValue: TFPRepository);
   Protected
     Function CurrentStreamVersion : Integer; override;
   Public
@@ -164,6 +167,7 @@ type
     Function AddPackage(const APackageName : string) : TFPPackage;
     Property StreamVersion : Integer Read FVersion Write FVersion;
     Property Packages [Index : Integer] : TFPPackage Read GetPackage Write SetPackage; default;
+    Property Repository: TFPRepository read FRepository write SetRepository;
   end;
   TFPPackagesClass = class of TFPPackages;
 
@@ -206,6 +210,7 @@ type
     Function AddPackage(const APackageName : string) : TFPPackage;
     // Dependencies
     Procedure GetPackageDependencies(const APackageName : String; List : TObjectList; Recurse : Boolean);
+    function PackageIsBroken(APackage: TFPPackage): Boolean;
     // Properties
     Property FileName : String Read FFileName;
     Property Packages[Index : Integer] : TFPPackage Read GetPackage; default;
@@ -277,6 +282,8 @@ Implementation
 uses
   typinfo,
   pkgglobals,
+  pkgmessages,
+  pkgrepos,
   fpxmlrep,
   uriparser;
 
@@ -417,6 +424,14 @@ begin
     Result:=FFileName;
 end;
 
+function TFPPackage.GetRepository: TFPRepository;
+begin
+  if Assigned(Collection) and (Collection is TFPPackages) then
+    Result := TFPPackages(Collection).Repository
+  else
+    Result := nil;
+end;
+
 
 procedure TFPPackage.LoadFromStream(Stream: TStream; Streamversion : Integer);
 Var
@@ -592,11 +607,19 @@ begin
 end;
 
 
-function TFPPackage.AddDependency(Const APackageName : String; const AMinVersion : String = ''): TFPDependency;
+function TFPPackage.AddDependency(Const APackageName : String; const AMinVersion: String = ''): TFPDependency;
 begin
   Result:=Dependencies.AddDependency(APackageName,AMinVersion);
 end;
 
+function TFPPackage.IsPackageBroken: Boolean;
+begin
+  if Assigned(Repository) then
+    Result := Repository.PackageIsBroken(Self)
+  else
+    raise Exception.Create(SErrRepositoryNotAssigned);
+end;
+
 
 { TFPPackages }
 
@@ -610,6 +633,15 @@ begin
    Items[Index]:=AValue;
 end;
 
+procedure TFPPackages.SetRepository(AValue: TFPRepository);
+begin
+  if FRepository = AValue then Exit;
+  if Assigned(FRepository) then
+    raise Exception.Create(SErrCannotModifyRepository)
+  else
+    FRepository := AValue;
+end;
+
 function TFPPackages.CurrentStreamVersion: Integer;
 begin
   Result:=FVersion;
@@ -670,6 +702,57 @@ begin
   Result:=FPackages.Count;
 end;
 
+function TFPRepository.PackageIsBroken(APackage: TFPPackage): Boolean;
+var
+  j, i, ThisRepositoryIndex: Integer;
+  Dependency: TFPDependency;
+  Repository: TFPRepository;
+  DepPackage: TFPPackage;
+begin
+  result:=false;
+
+  // We should only check for dependencies in this repository, or repositories
+  // with a lower priority.
+  ThisRepositoryIndex := -1;
+  for i := GFPpkg.RepositoryList.Count -1 downto 0 do
+    begin
+      if GFPpkg.RepositoryList.Items[i] = Self then
+        ThisRepositoryIndex := i;
+    end;
+
+  for j:=0 to APackage.Dependencies.Count-1 do
+    begin
+      Dependency:=APackage.Dependencies[j];
+      if (GFPpkg.CompilerOptions.CompilerOS in Dependency.OSes) and
+         (GFPpkg.CompilerOptions.CompilerCPU in Dependency.CPUs) then
+        begin
+          for i := ThisRepositoryIndex downto 0 do
+            begin
+              Repository := GFPpkg.RepositoryList.Items[i] as TFPRepository;
+              DepPackage := Repository.FindPackage(Dependency.FPackageName);
+              if Assigned(DepPackage) then
+                Break;
+            end;
+
+          if assigned(DepPackage) then
+            begin
+              if (Dependency.RequireChecksum<>$ffffffff) and (DepPackage.Checksum<>Dependency.RequireChecksum) then
+                begin
+                  log(llInfo,SLogPackageChecksumChanged,[APackage.Name,Self.RepositoryName,Dependency.PackageName,Repository.RepositoryName]);
+                  result:=true;
+                  exit;
+                end;
+            end
+          else
+            begin
+              log(llDebug,SDbgObsoleteDependency,[APackage.Name,Dependency.PackageName]);
+              result:=true;
+              exit;
+            end;
+        end;
+    end;
+end;
+
 constructor TFPRepository.Create(AOwner: TComponent);
 begin
   inherited Create(AOwner);
@@ -682,6 +765,7 @@ procedure TFPRepository.CreatePackages;
 begin
   FPackages:=TFPPackages.Create(TFPPackage);
   FPackages.StreamVersion:=StreamVersion;
+  FPackages.Repository:=Self;
 end;
 
 procedure TFPRepository.BackupFile(const AFileName: String);

+ 1 - 1
packages/fppkg/src/pkgcommands.pp

@@ -531,7 +531,7 @@ begin
                 end
               else
                 begin
-                  if PackageIsBroken(InstalledP, True) then
+                  if InstalledP.IsPackageBroken then
                     begin
                       status:='Broken, recompiling';
                       L.Add(D.PackageName);

+ 1 - 2
packages/fppkg/src/pkgfpmake.pp

@@ -324,8 +324,7 @@ begin
     AddOption('--debug')
   else if llInfo in LogLevels then
     AddOption('--verbose');
-  if P.RecompileBroken and
-     (P.FPMakeOptionsString<>'') then // Check for a empty FPMakeOptionString for packages being installed with an old fpmkunit
+  if (P.FPMakeOptionsString<>'') then
     begin
       // When the package is being reinstalled because of broken dependencies, use the same fpmake-options
       // as were used to compile the package in the first place.

+ 3 - 1
packages/fppkg/src/pkgmessages.pp

@@ -54,6 +54,8 @@ Resourcestring
   SErrGETFailed              = 'FTP GET "%s" command failed.';
   SErrBrokenPackagesFound    = 'Found broken packages, run "fppkg fixbroken" first';
   SErrManifestNoSinglePackage = 'Manifest file "%s" does not contain exactly one package';
+  SErrCannotModifyRepository = 'The repository of an TFPPackages-instance can not be changed.';
+  SErrRepositoryNotAssigned  = 'Repository not assigned';
 
   SLogGeneratingFPMake       = 'Generating fpmake.pp';
   SLogNotCompilingFPMake     = 'Skipping compiling of fpmake.pp, fpmake executable already exists';
@@ -84,7 +86,7 @@ Resourcestring
   SLogUpgradingConfig        = 'Configuration file "%s" is updated with new configuration settings';
   SLogOldConfigFileFormat    = 'Configuration file is in an old format';
   SLogPackageDependency      = 'Dependency on package %s %s, installed %s, available %s  (%s)';
-  SLogPackageChecksumChanged = 'Package %s needs to be rebuild, dependency %s is modified';
+  SLogPackageChecksumChanged = 'Package %s (%s) needs to be rebuild, dependency %s (%s) is modified';
   SLogCheckBrokenDependenvies= 'Checking for broken dependencies';
   SLogFailedToCreateManifest = 'Failed to create manifest from fpmake.pp-file (%s) while scanning for available packages: %s';
   SLogUseInternalFpmkunit    = 'Fpmkunit not available, fallback to internal version.';

+ 1 - 1
packages/fppkg/src/pkgoptions.pp

@@ -738,7 +738,7 @@ end;
 function TFppkgOptions.GetGlobalSection: TFppkgGLobalOptionSection;
 begin
   Result := GetSectionByName(KeyGlobalSection) as TFppkgGlobalOptionSection;
-  // Below version 5 the glolbal-section was called 'Defaults'
+  // Below version 5 the global-section was called 'Defaults'
   if not Assigned(Result) then
     Result := GetSectionByName(KeyDeprGlobalSection) as TFppkgGlobalOptionSection;
 

+ 20 - 55
packages/fppkg/src/pkgrepos.pp

@@ -16,7 +16,6 @@ procedure LoadLocalAvailableMirrors;
 function LoadManifestFromFile(const AManifestFN:string):TFPPackage;
 procedure FindInstalledPackages(ACompilerOptions:TCompilerOptions;showdups:boolean=true);
 Procedure AddFPMakeAddIn(APackage: TFPPackage);
-function  PackageIsBroken(APackage:TFPPackage; MarkForReInstall: boolean):boolean;
 function  FindBrokenPackages(SL:TStrings):Boolean;
 procedure CheckFPMakeDependencies;
 procedure ListPackages(const ShowGlobalAndLocal: boolean);
@@ -204,69 +203,35 @@ begin
 end;
 
 
-function PackageIsBroken(APackage:TFPPackage; MarkForReInstall: boolean):boolean;
+function FindBrokenPackages(SL:TStrings):Boolean;
 var
-  j : integer;
-  D : TFPDependency;
-  DepPackage : TFPPackage;
-  AvailP: TFPPackage;
+  i,j,k : integer;
+  P : TFPPackage;
+  Repo: TFPRepository;
 begin
-  result:=false;
-  for j:=0 to APackage.Dependencies.Count-1 do
+  SL.Clear;
+  for i:=0 to GFPpkg.RepositoryList.Count-1 do
     begin
-      D:=APackage.Dependencies[j];
-      if (GFPpkg.CompilerOptions.CompilerOS in D.OSes) and
-         (GFPpkg.CompilerOptions.CompilerCPU in D.CPUs) then
+      Repo := TFPRepository(GFPpkg.RepositoryList[i]);
+      if Repo.RepositoryType = fprtInstalled then
         begin
-          DepPackage:=GFPpkg.FindPackage(D.PackageName, pkgpkInstalled);
-          // Don't stop on missing dependencies
-          if assigned(DepPackage) then
+          for j := 0 to Repo.PackageCount-1 do
             begin
-              if (D.RequireChecksum<>$ffffffff) and (DepPackage.Checksum<>D.RequireChecksum) then
+              P := Repo.Packages[j];
+              if P.IsPackageBroken then
+                SL.Add(P.Name)
+              else
                 begin
-                  log(llInfo,SLogPackageChecksumChanged,[APackage.Name,D.PackageName]);
-                  result:=true;
-                  if MarkForReInstall then
-                    begin
-                      APackage.RecompileBroken:=true;
-                    end;
-                  exit;
-                end;
-            end
-          else
-            begin
-              log(llDebug,SDbgObsoleteDependency,[APackage.Name,D.PackageName]);
-              result:=true;
-              if MarkForReInstall then
-                begin
-                  APackage.RecompileBroken:=true;
+                  // It could be that a package is broken in one repository,
+                  // but that this problem is 'fixed' in a repository with an higher
+                  // priority
+                  k := SL.IndexOf(P.Name);
+                  if k > -1 then
+                    SL.Delete(k);
                 end;
             end;
         end;
     end;
-end;
-
-
-function FindBrokenPackages(SL:TStrings):Boolean;
-var
-  i,j : integer;
-  P : TFPPackage;
-  Repo: TFPRepository;
-begin
-  SL.Clear;
-  for i:= 0 to GFPpkg.RepositoryList.Count-1 do
-    begin
-      Repo := GFPpkg.RepositoryList.Items[i] as TFPRepository;
-      if Repo.RepositoryType=fprtInstalled then
-        for j:=0 to Repo.PackageCount-1 do
-          begin
-            P:=Repo.Packages[j];
-            if PackageIsBroken(P,True) then
-              begin
-                SL.Add(P.Name);
-              end;
-          end;
-    end;
   Result:=(SL.Count>0);
 end;
 
@@ -327,7 +292,7 @@ procedure ListPackages(const ShowGlobalAndLocal: boolean);
     if Assigned(APackage) then
       begin
         PackageVersion := APackage.Version.AsString;
-        if CheckIsBroken and PackageIsBroken(APackage, False) then
+        if CheckIsBroken and APackage.IsPackageBroken then
           PackageVersion := PackageVersion + ' (B)';
       end
     else