* Adapted tests for broken dependencies (packages)

* Reload AddIn-state after an AddIn has been compiled
 * Fixed re-compilation of already installed packages, based on the original
   sources
 * Improved the algorithm to determine which package to use when a package
   is being build based on package-name

git-svn-id: trunk@35533 -
This commit is contained in:
joost 2017-03-06 22:19:43 +00:00
parent a2bd07bfd6
commit 2a01a603d8
6 changed files with 194 additions and 87 deletions

View File

@ -365,7 +365,14 @@ end;
function TFPCustomPackagesStructure.GetBuildPathDirectory(APackage: TFPPackage): string;
begin
Result := '';
if (APackage.Repository.RepositoryType=fprtInstalled) and (APackage.SourcePath<>'') then
begin
Result := APackage.SourcePath;
end
else
begin
Result := '';
end;
end;
function TFPCustomPackagesStructure.GetPrefix: string;

View File

@ -562,7 +562,7 @@ begin
end
else
begin
if PackageManager.PackageIsBroken(InstalledP, InstalledP.Repository) then
if PackageManager.PackageIsBroken(InstalledP, nil) then
begin
status:='Broken, recompiling';
L.Add(D.PackageName);
@ -610,10 +610,12 @@ procedure TCommandFixBroken.Execute;
var
i : integer;
SL : TStringList;
BreakLoop : Boolean;
begin
SL:=TStringList.Create;
BreakLoop := false;
repeat
FindBrokenPackages(SL);
PackageManager.FindBrokenPackages(SL);
if SL.Count=0 then
break;
pkgglobals.Log(llProgres,SProgrReinstallDependent);
@ -621,8 +623,13 @@ begin
begin
ExecuteAction(SL[i],'build');
ExecuteAction(SL[i],'install-req');
if PackageManager.PackageIsBroken(PackageManager.PackageByName(SL[i], pkgpkInstalled), nil) then
begin
BreakLoop := true;
pkgglobals.Log(llWarning, SWarnBrokenAfterReinstall, [SL[i]]);
end;
end;
until false;
until BreakLoop;
FreeAndNil(SL);
end;

View File

@ -23,6 +23,8 @@ type
{ TFPMakeCompiler }
TFPMakeCompiler = Class(TPackagehandler)
protected
function DeterminePackage: TFPPackage;
Public
Procedure Execute;override;
end;
@ -30,7 +32,7 @@ type
{ TFPMakeRunner }
TFPMakeRunner = Class(TPackagehandler)
TFPMakeRunner = Class(TFPMakeCompiler)
Protected
Function RunFPMake(const Command:string):Integer;
end;
@ -132,6 +134,28 @@ end;
{ TFPMakeCompiler }
function TFPMakeCompiler.DeterminePackage: TFPPackage;
var
PA, PI: TFPPackage;
begin
PA:=PackageManager.FindPackage(PackageName, pkgpkAvailable);
PI:=PackageManager.FindPackage(PackageName, pkgpkInstalled);
if Assigned(PA) and Assigned(PI) then
begin
if PA.Version.CompareVersion(PI.Version) > 0 then
Result := PA
else
Result := PI;
end
else if Assigned(PI) then
Result := PI
else
Result := PA;
if not Assigned(Result) then
Raise EPackage.CreateFmt(SErrMissingPackage,[PackageName]);
end;
Procedure TFPMakeCompiler.Execute;
var
OOptions : string;
@ -168,7 +192,7 @@ Var
FPMKUnitDepPackage: TFPPackage;
P : TFPPackage;
begin
P:=PackageManager.PackageByName(PackageName, pkgpkAvailable);
P:=DeterminePackage;
NeedFPMKUnitSource:=false;
OOptions:='';
SetCurrentDir(PackageManager.PackageBuildPath(P));
@ -323,7 +347,7 @@ begin
// Does the current package support this CPU-OS?
if PackageName<>'' then
begin
P:=PackageManager.PackageByName(PackageName, pkgpkAvailable);
P := DeterminePackage;
if (PackageName=CurrentDirPackageName) and (FileExists(ManifestFileName)) then
ObtainSupportedTargetsFromManifest(p);
end

View File

@ -21,6 +21,9 @@ type
TpkgPackageKind = (pkgpkInstalled, pkgpkAvailable, pkgpkBoth);
TpkgFPpkg = class(TComponent)
private
FInsideFindBrokenPackages: Integer;
FBrokenPackagesDictionary: TFPHashList;
FFPMakeRepositoryList: TComponentList;
FRepositoryList: TComponentList;
FOptions: TFppkgOptions;
@ -35,6 +38,8 @@ type
function FindPackage(ARepositoryList: TComponentList; APackageName: string; APackageKind: TpkgPackageKind): TFPPackage;
function SelectRemoteMirror:string;
procedure EnterFindBrokenPackages;
procedure LeaveFindBrokenpackages;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
@ -63,6 +68,7 @@ type
procedure ScanInstalledPackagesForAvailablePackages;
procedure CheckFPMakeDependencies;
function FindBrokenPackages(SL:TStrings):Boolean;
property Options: TFppkgOptions read FOptions;
property CompilerOptions: TCompilerOptions read FCompilerOptions;
@ -90,10 +96,12 @@ begin
FFpmakeCompilerOptions := TCompilerOptions.Create;
FRepositoryList := TComponentList.Create(False);
FFPMakeRepositoryList := TComponentList.Create(False);
FBrokenPackagesDictionary := TFPHashList.Create;
end;
destructor TpkgFPpkg.Destroy;
begin
FBrokenPackagesDictionary.Free;
FFPMakeRepositoryList.Free;
FRepositoryList.Free;
FCompilerOptions.Free;
@ -321,57 +329,82 @@ var
Dependency: TFPDependency;
Repository: TFPRepository;
DepPackage: TFPPackage;
HashPtr: PtrInt;
begin
result:=false;
if not Assigned(ARepository) then
begin
// Check with all repositories
ThisRepositoryIndex := RepositoryList.Count -1;
end
else
begin
// We should only check for dependencies in this repository, or repositories
// with a lower priority.
ThisRepositoryIndex := -1;
for i := RepositoryList.Count -1 downto 0 do
EnterFindBrokenPackages;
try
HashPtr := PtrInt(FBrokenPackagesDictionary.Find(APackage.Name));
if HashPtr<>0 then
begin
if RepositoryList.Items[i] = ARepository then
ThisRepositoryIndex := i;
// Package is already evaluated
Result := (HashPtr = 1);
Exit;
end;
end;
for j:=0 to APackage.Dependencies.Count-1 do
begin
Dependency:=APackage.Dependencies[j];
if (CompilerOptions.CompilerOS in Dependency.OSes) and
(CompilerOptions.CompilerCPU in Dependency.CPUs) then
if not Assigned(ARepository) then
begin
// Check with all repositories
ThisRepositoryIndex := RepositoryList.Count -1;
end
else
begin
// We should only check for dependencies in this repository, or repositories
// with a lower priority.
ThisRepositoryIndex := -1;
for i := RepositoryList.Count -1 downto 0 do
begin
for i := ThisRepositoryIndex downto 0 do
begin
Repository := RepositoryList.Items[i] as TFPRepository;
DepPackage := Repository.FindPackage(Dependency.PackageName);
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,APackage.Repository.RepositoryName,Dependency.PackageName,Repository.RepositoryName]);
result:=true;
exit;
end;
end
else
begin
log(llDebug,SDbgObsoleteDependency,[APackage.Name,Dependency.PackageName]);
result:=true;
exit;
end;
if RepositoryList.Items[i] = ARepository then
ThisRepositoryIndex := i;
end;
end;
end;
for j:=0 to APackage.Dependencies.Count-1 do
begin
Dependency:=APackage.Dependencies[j];
if (CompilerOptions.CompilerOS in Dependency.OSes) and
(CompilerOptions.CompilerCPU in Dependency.CPUs) then
begin
DepPackage := nil;
for i := ThisRepositoryIndex downto 0 do
begin
Repository := RepositoryList.Items[i] as TFPRepository;
if Repository.RepositoryType=fprtInstalled then
DepPackage := Repository.FindPackage(Dependency.PackageName);
if Assigned(DepPackage) then
Break;
end;
if assigned(DepPackage) then
begin
if PackageIsBroken(DepPackage, ARepository) then
begin
log(llInfo,SLogPackageDepBroken,[APackage.Name,APackage.Repository.RepositoryName,Dependency.PackageName,Repository.RepositoryName]);
result:=true;
FBrokenPackagesDictionary.Add(APackage.Name, Pointer(1));
exit;
end;
if (Dependency.RequireChecksum<>$ffffffff) and (DepPackage.Checksum<>Dependency.RequireChecksum) then
begin
log(llInfo,SLogPackageChecksumChanged,[APackage.Name,APackage.Repository.RepositoryName,Dependency.PackageName,Repository.RepositoryName]);
result:=true;
FBrokenPackagesDictionary.Add(APackage.Name, Pointer(1));
exit;
end;
end
else
begin
log(llInfo,SDbgObsoleteDependency,[APackage.Name,Dependency.PackageName]);
result:=true;
FBrokenPackagesDictionary.Add(APackage.Name, Pointer(1));
exit;
end;
end;
end;
FBrokenPackagesDictionary.Add(APackage.Name, Pointer(2));
finally
LeaveFindBrokenpackages;
end;
end;
function TpkgFPpkg.FPMakeRepoFindPackage(APackageName: string;
@ -446,6 +479,20 @@ begin
Error(SErrFailedToSelectMirror);
end;
procedure TpkgFPpkg.EnterFindBrokenPackages;
begin
Assert((FInsideFindBrokenPackages>0) or (FBrokenPackagesDictionary.Count=0));
Inc(FInsideFindBrokenPackages)
end;
procedure TpkgFPpkg.LeaveFindBrokenpackages;
begin
Assert(FInsideFindBrokenPackages>0);
Dec(FInsideFindBrokenPackages);
if FInsideFindBrokenPackages=0 then
FBrokenPackagesDictionary.Clear;
end;
function TpkgFPpkg.PackageByName(APackageName: string; APackageKind: TpkgPackageKind): TFPPackage;
var
ErrStr: string;
@ -578,6 +625,34 @@ begin
end;
end;
function TpkgFPpkg.FindBrokenPackages(SL: TStrings): Boolean;
var
i,j,k : integer;
P : TFPPackage;
Repo: TFPRepository;
begin
SL.Clear;
EnterFindBrokenPackages;
try
for i:=0 to RepositoryList.Count-1 do
begin
Repo := TFPRepository(RepositoryList[i]);
if Repo.RepositoryType = fprtInstalled then
begin
for j := 0 to Repo.PackageCount-1 do
begin
P := Repo.Packages[j];
if (P = FindPackage(P.Name, pkgpkInstalled)) and PackageIsBroken(P, nil) then
SL.Add(P.Name);
end;
end;
end;
finally
LeaveFindBrokenpackages;
end;
Result:=(SL.Count>0);
end;
function TpkgFPpkg.PackageBuildPath(APackage: TFPPackage): String;
begin
if (APackage.Name=CmdLinePackageName) or (APackage.Name=URLPackageName) then

View File

@ -20,7 +20,7 @@ Resourcestring
SErrMissingCompilerConfig = 'Could not find compiler configuration "%s"';
SErrMissingInstallPackage = 'Package "%s" is not installed';
SErrMissingAvailablePackage= 'Package "%s" is not available';
SErrMissingPackage = 'Could not fin package "%s"';
SErrMissingPackage = 'Could not find package "%s"';
SErrMissingInstallRepo = 'Could not find repository "%s"';
SErrNoPackageSpecified = 'No package specified';
SErrNoPackageAvailable = 'Package %s %s is not available';
@ -80,6 +80,7 @@ Resourcestring
SLogLoadingMirrorsFile = 'Loading available mirrors from "%s"';
SLogFindInstalledPackages = 'Searching for installed packages in "%s"';
SLogFoundFPMakeAddin = 'Found FPMake-AddIn "%s"';
SLogUpdateFPMakeAddin = 'FPMake-AddIn "%s" updated';
SLogSavingStatusFile = 'Saving local status to "%s"';
SLogFPMKUnitDepVersion = 'Checking for %s %s, installed %s, available %s';
SLogFPMKUnitDepTooOld = 'Minimum version of %s is not installed, using internal fpmkunit with limited functionality';
@ -89,6 +90,7 @@ Resourcestring
SLogOldConfigFileFormat = 'Configuration file is in an old format';
SLogPackageDependency = 'Dependency on package %s %s, installed %s, available %s (%s)';
SLogPackageChecksumChanged = 'Package %s (%s) needs to be rebuild, dependency %s (%s) is modified';
SLogPackageDepBroken = 'Package %s (%s) needs to be rebuild, dependency %s (%s) is broken';
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.';
@ -146,6 +148,8 @@ Resourcestring
SDbgPackageDependencyOtherTarget = 'Dependency on package %s is not for %s';
SDbgObsoleteDependency = 'Package %s depends on package %s which is not installed anymore';
SWarnBrokenAfterReinstall = 'Package %s is still broken, even after re-installation.';
SProgrReinstallDependent = 'Re-install packages which are dependent on just installed packages';
SProgrInstallDependencies = 'Install dependencies';
SProgrDependenciesInstalled= 'Dependencies installed';

View File

@ -145,47 +145,37 @@ end;
Procedure AddFPMakeAddIn(APackage: TFPPackage);
var
SelectedDep, i: Integer;
begin
log(llDebug,SLogFoundFPMakeAddin,[APackage.Name]);
setlength(FPMKUnitDeps,length(FPMKUnitDeps)+1);
FPMKUnitDeps[high(FPMKUnitDeps)].package:=APackage.Name;
FPMKUnitDeps[high(FPMKUnitDeps)].reqver:=APackage.Version.AsString;
FPMKUnitDeps[high(FPMKUnitDeps)].def:='HAS_PACKAGE_'+APackage.Name;
FPMKUnitDeps[high(FPMKUnitDeps)].PluginUnit:=APackage.FPMakePluginUnits;
FPMKUnitDeps[high(FPMKUnitDeps)].available:=true;
SelectedDep := -1;
for i := 0 to high(FPMKUnitDeps) do
begin
if FPMKUnitDeps[i].package = APackage.Name then
begin
log(llDebug,SLogUpdateFPMakeAddin,[APackage.Name]);
SelectedDep := i;
break;
end;
end;
if SelectedDep = -1 then
begin
log(llDebug,SLogFoundFPMakeAddin,[APackage.Name]);
setlength(FPMKUnitDeps,length(FPMKUnitDeps)+1);
SelectedDep := high(FPMKUnitDeps);
end;
FPMKUnitDeps[SelectedDep].package:=APackage.Name;
FPMKUnitDeps[SelectedDep].reqver:=APackage.Version.AsString;
FPMKUnitDeps[SelectedDep].def:='HAS_PACKAGE_'+APackage.Name;
FPMKUnitDeps[SelectedDep].PluginUnit:=APackage.FPMakePluginUnits;
FPMKUnitDeps[SelectedDep].available:=true;
end;
function FindBrokenPackages(SL:TStrings):Boolean;
var
i,j,k : integer;
P : TFPPackage;
Repo: TFPRepository;
begin
SL.Clear;
for i:=0 to GFPpkg.RepositoryList.Count-1 do
begin
Repo := TFPRepository(GFPpkg.RepositoryList[i]);
if Repo.RepositoryType = fprtInstalled then
begin
for j := 0 to Repo.PackageCount-1 do
begin
P := Repo.Packages[j];
if P.IsPackageBroken then
SL.Add(P.Name)
else
begin
// 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;
Result:=(SL.Count>0);
Result := GFPpkg.FindBrokenPackages(SL);
end;