* split repository in InstalledRepository and AvailableRepository

* replace CurrentPackage by PackageName
  * remove obsolete execute arguments

git-svn-id: trunk@10610 -
This commit is contained in:
peter 2008-04-06 21:00:24 +00:00
parent 347ae5a3bf
commit 85250cca06
9 changed files with 467 additions and 561 deletions

View File

@ -30,7 +30,6 @@ Type
TMakeTool = Class(TCustomApplication)
Private
ActionStack : TActionStack;
ParaAction : string;
ParaPackages : TStringList;
procedure MaybeCreateLocalDirs;
@ -174,13 +173,11 @@ Constructor TMakeTool.Create;
begin
inherited Create(nil);
ParaPackages:=TStringList.Create;
ActionStack:=TActionStack.Create;
end;
Destructor TMakeTool.Destroy;
begin
FreeAndNil(ActionStack);
FreeAndNil(ParaPackages);
inherited Destroy;
end;
@ -275,7 +272,6 @@ procedure TMakeTool.DoRun;
var
ActionPackage : TFPPackage;
OldCurrDir : String;
Res : Boolean;
i : Integer;
SL : TStringList;
begin
@ -292,14 +288,14 @@ begin
if not FileExists(GlobalOptions.LocalPackagesFile) then
begin
try
pkghandler.ExecuteAction(nil,'update');
pkghandler.ExecuteAction('','update');
except
on E: Exception do
Log(vlWarning,E.Message);
end;
end;
LoadLocalMirrors;
LoadLocalRepository;
LoadLocalAvailableMirrors;
LoadLocalAvailableRepository;
FindInstalledPackages(FPMakeCompilerOptions,true);
CheckFPMakeDependencies;
// We only need to reload the status when we use a different
@ -319,8 +315,8 @@ begin
if ParaPackages.Count=0 then
begin
Log(vlDebug,SLogCommandLineAction,['[<currentdir>]',ParaAction]);
res:=pkghandler.ExecuteAction(nil,ParaAction);
ActionPackage:=InstalledRepository.AddPackage(CurrentDirPackageName);
pkghandler.ExecuteAction(CurrentDirPackageName,ParaAction);
end
else
begin
@ -329,26 +325,21 @@ begin
begin
if FileExists(ParaPackages[i]) then
begin
ActionPackage:=LoadOrCreatePackage(ChangeFileExt(ExtractFileName(ParaPackages[i]),''));
ActionPackage.FileName:=ExpandFileName(ParaPackages[i]);
ActionPackage.IsLocalPackage:=true;
res:=pkghandler.ExecuteAction(ActionPackage,ParaAction);
FreeAndNil(ActionPackage);
ActionPackage:=InstalledRepository.AddPackage(CmdLinePackageName);
ActionPackage.LocalFileName:=ExpandFileName(ParaPackages[i]);
pkghandler.ExecuteAction(CmdLinePackageName,ParaAction);
end
else
begin
ActionPackage:=CurrentRepository.PackageByName(ParaPackages[i]);
Log(vlDebug,SLogCommandLineAction,['['+ActionPackage.Name+']',ParaAction]);
res:=pkghandler.ExecuteAction(ActionPackage,ParaAction);
Log(vlDebug,SLogCommandLineAction,['['+ParaPackages[i]+']',ParaAction]);
pkghandler.ExecuteAction(ParaPackages[i],ParaAction);
end;
if not res then
break;
end;
end;
// Recompile all packages dependent on this package
if res and (ParaAction='install') then
pkghandler.ExecuteAction(nil,'fixbroken');
if (ParaAction='install') then
pkghandler.ExecuteAction('','fixbroken');
Terminate;

View File

@ -122,9 +122,8 @@ type
FOSes : TOSES;
FCPUs : TCPUS;
// Installation info
FInstalledVersion : TFPVersion;
FInstalledChecksum : cardinal;
FIsLocalPackage : Boolean;
FChecksum : cardinal;
FLocalFileName : String;
function GetFileName: String;
procedure SetName(const AValue: String);
procedure SetVersion(const AValue: TFPVersion);
@ -134,7 +133,7 @@ type
Procedure LoadFromStream(Stream : TStream; Streamversion : Integer); override;
Procedure SaveToStream(Stream : TStream); override;
Procedure Assign(Source : TPersistent); override;
Function AddDependency(Const APackageName : String; AMinVersion : String = '') : TFPDependency;
Function AddDependency(Const APackageName : String; const AMinVersion : String = '') : TFPDependency;
Property Dependencies : TFPDependencies Read FDependencies;
Published
Property Name : String Read FName Write SetName;
@ -147,10 +146,9 @@ type
Property Email : String Read FEmail Write FEmail;
Property OSes : TOSes Read FOSes Write FOses;
Property CPUs : TCPUs Read FCPUs Write FCPUs;
Property InstalledVersion : TFPVersion Read FInstalledVersion Write FInstalledVersion;
Property InstalledChecksum : Cardinal Read FInstalledChecksum Write FInstalledChecksum;
Property Checksum : Cardinal Read FChecksum Write FChecksum;
// Manual package from commandline not in official repository
Property IsLocalPackage : Boolean Read FIsLocalPackage Write FIsLocalPackage;
Property LocalFileName : String Read FLocalFileName Write FLocalFileName;
end;
{ TFPPackages }
@ -194,14 +192,6 @@ type
Procedure LoadFromFile(const AFileName : String);
Procedure SaveToFile(const AFileName : String);
Procedure Save;
// Loading and Saving version numbers: List of Name=Value pairs.
procedure ClearStatus;
{$ifdef STATUSFILE}
Procedure LoadStatusFromStream(Stream : TStream); virtual;
Procedure SaveStatusToStream(Stream : TStream); virtual;
Procedure LoadStatusFromFile(const AFileName : String);
Procedure SaveStatusToFile(const AFileName : String);
{$endif STATUSFILE}
// Package management
Function IndexOfPackage(const APackageName : String) : Integer;
Function FindPackage(const APackageName : String) : TFPPackage;
@ -484,8 +474,7 @@ constructor TFPPackage.Create(ACollection: TCollection);
begin
inherited Create(ACollection);
FVersion:=TFPVersion.Create;
FInstalledVersion:=TFPVersion.Create;
FInstalledChecksum:=$ffffffff;
FChecksum:=$ffffffff;
FOSes:=AllOSes;
FCPUs:=AllCPUs;
FDependencies:=TFPDependencies.Create(TFPDependency);
@ -496,7 +485,6 @@ destructor TFPPackage.Destroy;
begin
FreeAndNil(FDependencies);
FreeAndNil(FVersion);
FreeAndNil(FInstalledVersion);
inherited Destroy;
end;
@ -621,7 +609,7 @@ begin
Description:=P.Description;
ExternalURL:=P.ExternalURL;
FileName:=P.FileName;
InstalledVersion.Assign(P.Installedversion);
Checksum:=P.Checksum;
Dependencies.Clear;
Dependencies.Assign(P.Dependencies);
end
@ -630,7 +618,7 @@ begin
end;
function TFPPackage.AddDependency(const APackageName: String;AMinVersion: String): TFPDependency;
function TFPPackage.AddDependency(Const APackageName : String; const AMinVersion : String = ''): TFPDependency;
begin
Result:=Dependencies.AddDependency(APackageName,AMinVersion);
end;
@ -808,85 +796,6 @@ begin
end;
procedure TFPRepository.ClearStatus;
Var
I : Integer;
begin
For I:=0 to PackageCount-1 do
With Packages[i] do
InstalledVersion.Clear;
end;
{$ifdef STATUSFILE}
procedure TFPRepository.LoadStatusFromStream(Stream: TStream);
Var
L : TStrings;
I : Integer;
N,V : String;
begin
L:=TStringList.Create;
Try
L.LoadFromStream(Stream);
For I:=0 to L.Count-1 do
begin
L.GetNameValue(I,N,V);
If (N<>'') and (V<>'') then
PackageByName(N).InstalledVersion.AsString:=V;
end;
Finally
L.Free;
end;
end;
procedure TFPRepository.SaveStatusToStream(Stream: TStream);
Var
L : TStrings;
I : Integer;
begin
L:=TStringList.Create;
Try
For I:=0 to PackageCount-1 do
With Packages[i] do
if not InstalledVersion.Empty then
L.Add(Name+'='+InstalledVersion.AsString);
L.SaveToStream(Stream);
Finally
L.Free;
end;
end;
procedure TFPRepository.LoadStatusFromFile(const AFileName: String);
Var
F : TFileStream;
begin
F:=TFileStream.Create(AFileName,fmOpenRead);
Try
LoadStatusFromStream(F);
Finally
F.Free;
end;
end;
procedure TFPRepository.SaveStatusToFile(const AFileName: String);
Var
F : TFileStream;
begin
If FileExists(AFileName) and BackupFiles then
BackupFile(AFileName);
F:=TFileStream.Create(AFileName,fmCreate);
Try
SaveStatusToStream(F);
Finally
F.Free;
end;
end;
{$endif STATUSFILE}
function TFPRepository.IndexOfPackage(const APackageName: String): Integer;
begin
Result:=FPackages.IndexOfPackage(APackageName);

View File

@ -23,176 +23,178 @@ type
TCommandAddConfig = Class(TPackagehandler)
Public
Function Execute(const Args:TActionArgs):boolean;override;
Procedure Execute;override;
end;
{ TCommandUpdate }
TCommandUpdate = Class(TPackagehandler)
Public
Function Execute(const Args:TActionArgs):boolean;override;
Procedure Execute;override;
end;
{ TCommandShowAll }
TCommandShowAll = Class(TPackagehandler)
Public
Function Execute(const Args:TActionArgs):boolean;override;
Procedure Execute;override;
end;
{ TCommandShowAvail }
TCommandShowAvail = Class(TPackagehandler)
Public
Function Execute(const Args:TActionArgs):boolean;override;
Procedure Execute;override;
end;
{ TCommandScanPackages }
TCommandScanPackages = Class(TPackagehandler)
Public
Function Execute(const Args:TActionArgs):boolean;override;
Procedure Execute;override;
end;
{ TCommandDownload }
TCommandDownload = Class(TPackagehandler)
Public
Function Execute(const Args:TActionArgs):boolean;override;
Procedure Execute;override;
end;
{ TCommandUnzip }
TCommandUnzip = Class(TPackagehandler)
Public
Function Execute(const Args:TActionArgs):boolean;override;
Procedure Execute;override;
end;
{ TCommandCompile }
TCommandCompile = Class(TPackagehandler)
Public
Function Execute(const Args:TActionArgs):boolean;override;
Procedure Execute;override;
end;
{ TCommandBuild }
TCommandBuild = Class(TPackagehandler)
Public
Function Execute(const Args:TActionArgs):boolean;override;
Procedure Execute;override;
end;
{ TCommandInstall }
TCommandInstall = Class(TPackagehandler)
Public
Function Execute(const Args:TActionArgs):boolean;override;
Procedure Execute;override;
end;
{ TCommandClean }
TCommandClean = Class(TPackagehandler)
Public
Function Execute(const Args:TActionArgs):boolean;override;
Procedure Execute;override;
end;
{ TCommandArchive }
TCommandArchive = Class(TPackagehandler)
Public
Function Execute(const Args:TActionArgs):boolean;override;
Procedure Execute;override;
end;
{ TCommandInstallDependencies }
TCommandInstallDependencies = Class(TPackagehandler)
Public
Function Execute(const Args:TActionArgs):boolean;override;
Procedure Execute;override;
end;
{ TCommandFixBroken }
TCommandFixBroken = Class(TPackagehandler)
Public
Function Execute(const Args:TActionArgs):boolean;override;
Procedure Execute;override;
end;
function TCommandAddConfig.Execute(const Args:TActionArgs):boolean;
procedure TCommandAddConfig.Execute;
begin
{
Log(vlInfo,SLogGeneratingCompilerConfig,[S]);
Options.InitCompilerDefaults(Args[2]);
Options.SaveCompilerToFile(S);
}
Result:=true;
end;
function TCommandUpdate.Execute(const Args:TActionArgs):boolean;
procedure TCommandUpdate.Execute;
var
PackagesURL : String;
begin
// Download mirrors.xml
Log(vlCommands,SLogDownloading,[GlobalOptions.RemoteMirrorsURL,GlobalOptions.LocalMirrorsFile]);
DownloadFile(GlobalOptions.RemoteMirrorsURL,GlobalOptions.LocalMirrorsFile);
LoadLocalMirrors;
LoadLocalAvailableMirrors;
// Download packages.xml
PackagesURL:=GetRemoteRepositoryURL(PackagesFileName);
Log(vlCommands,SLogDownloading,[PackagesURL,GlobalOptions.LocalPackagesFile]);
DownloadFile(PackagesURL,GlobalOptions.LocalPackagesFile);
// Read the repository again
LoadLocalRepository;
LoadLocalAvailableRepository;
// no need to log errors again
FindInstalledPackages(CompilerOptions,False);
Result:=true;
end;
function TCommandShowAll.Execute(const Args:TActionArgs):boolean;
procedure TCommandShowAll.Execute;
begin
ListLocalRepository(true);
Result:=true;
ListInstalledPackages;
end;
function TCommandShowAvail.Execute(const Args:TActionArgs):boolean;
procedure TCommandShowAvail.Execute;
begin
ListLocalRepository(false);
Result:=true;
ListAvailablePackages;
end;
function TCommandScanPackages.Execute(const Args:TActionArgs):boolean;
procedure TCommandScanPackages.Execute;
begin
RebuildRemoteRepository;
ListRemoteRepository;
SaveRemoteRepository;
Result:=true;
end;
function TCommandDownload.Execute(const Args:TActionArgs):boolean;
procedure TCommandDownload.Execute;
var
P : TFPPackage;
begin
if not assigned(CurrentPackage) then
if PackageName='' then
Error(SErrNoPackageSpecified);
if not FileExists(PackageLocalArchive) then
ExecuteAction(CurrentPackage,'downloadpackage',Args);
Result:=true;
P:=AvailableRepository.PackageByName(PackageName);
if not FileExists(PackageLocalArchive(P)) then
ExecuteAction(PackageName,'downloadpackage');
end;
function TCommandUnzip.Execute(const Args:TActionArgs):boolean;
procedure TCommandUnzip.Execute;
Var
BuildDir : string;
ArchiveFile : String;
P : TFPPackage;
begin
BuildDir:=PackageBuildPath;
ArchiveFile:=PackageLocalArchive;
if not assigned(CurrentPackage) then
if PackageName='' then
Error(SErrNoPackageSpecified);
if IsLocalPackage then
P:=InstalledRepository.PackageByName(PackageName)
else
P:=AvailableRepository.PackageByName(PackageName);
BuildDir:=PackageBuildPath(P);
ArchiveFile:=PackageLocalArchive(P);
if not FileExists(ArchiveFile) then
ExecuteAction(CurrentPackage,'downloadpackage');
ExecuteAction(PackageName,'downloadpackage');
{ Create builddir, remove it first if needed }
if DirectoryExists(BuildDir) then
DeleteDir(BuildDir);
@ -202,130 +204,141 @@ begin
With TUnZipper.Create do
try
Log(vlCommands,SLogUnzippping,[ArchiveFile]);
OutputPath:=PackageBuildPath;
OutputPath:=PackageBuildPath(P);
UnZipAllFiles(ArchiveFile);
Finally
Free;
end;
Result:=true;
end;
function TCommandCompile.Execute(const Args:TActionArgs):boolean;
procedure TCommandCompile.Execute;
begin
if assigned(CurrentPackage) then
if PackageName<>'' then
begin
// For local files we need the information inside the zip to get the
// dependencies
if CurrentPackage.IsLocalPackage then
if IsLocalPackage then
begin
ExecuteAction(CurrentPackage,'unzip',Args);
ExecuteAction(CurrentPackage,'installdependencies',Args);
ExecuteAction(PackageName,'unzip');
ExecuteAction(PackageName,'installdependencies');
end
else
begin
ExecuteAction(CurrentPackage,'installdependencies',Args);
ExecuteAction(CurrentPackage,'unzip',Args);
ExecuteAction(PackageName,'installdependencies');
ExecuteAction(PackageName,'unzip');
end;
end;
ExecuteAction(CurrentPackage,'fpmakecompile',Args);
Result:=true;
ExecuteAction(PackageName,'fpmakecompile');
end;
function TCommandBuild.Execute(const Args:TActionArgs):boolean;
procedure TCommandBuild.Execute;
begin
if assigned(CurrentPackage) then
if PackageName<>'' then
begin
// For local files we need the information inside the zip to get the
// dependencies
if CurrentPackage.IsLocalPackage then
if IsLocalPackage then
begin
ExecuteAction(CurrentPackage,'unzip',Args);
ExecuteAction(CurrentPackage,'installdependencies',Args);
ExecuteAction(PackageName,'unzip');
ExecuteAction(PackageName,'installdependencies');
end
else
begin
ExecuteAction(CurrentPackage,'installdependencies',Args);
ExecuteAction(CurrentPackage,'unzip',Args);
ExecuteAction(PackageName,'installdependencies');
ExecuteAction(PackageName,'unzip');
end;
end;
ExecuteAction(CurrentPackage,'fpmakebuild',Args);
Result:=true;
ExecuteAction(PackageName,'fpmakebuild');
end;
function TCommandInstall.Execute(const Args:TActionArgs):boolean;
procedure TCommandInstall.Execute;
var
S : String;
UFN,S : String;
P : TFPPackage;
begin
if assigned(CurrentPackage) then
ExecuteAction(CurrentPackage,'build',Args);
ExecuteAction(CurrentPackage,'fpmakeinstall',Args);
// Update version information from generated fpunits.conf
if assigned(CurrentPackage) then
if PackageName<>'' then
begin
if GlobalOptions.InstallGlobal then
S:=CompilerOptions.GlobalUnitDir
ExecuteAction(PackageName,'build');
ExecuteAction(PackageName,'fpmakeinstall');
if IsLocalPackage then
begin
// Load package name from manifest
if not FileExists(ManifestFileName) then
ExecuteAction(PackageName,'fpmakemanifest');
P:=LoadManifestFromFile(ManifestFileName);
S:=P.Name;
FreeAndNil(P);
end
else
S:=CompilerOptions.LocalUnitDir;
S:=IncludeTrailingPathDelimiter(S)+CurrentPackage.Name+PathDelim+UnitConfigFileName;
LoadUnitConfigFromFile(CurrentPackage,S);
end;
Result:=true;
S:=PackageName;
P:=InstalledRepository.FindPackage(S);
if not assigned(P) then
P:=InstalledRepository.AddPackage(S);
if GlobalOptions.InstallGlobal then
UFN:=CompilerOptions.GlobalUnitDir
else
UFN:=CompilerOptions.LocalUnitDir;
UFN:=IncludeTrailingPathDelimiter(UFN)+S+PathDelim+UnitConfigFileName;
LoadUnitConfigFromFile(P,UFN);
end
else
ExecuteAction(PackageName,'fpmakeinstall');
end;
function TCommandClean.Execute(const Args:TActionArgs):boolean;
procedure TCommandClean.Execute;
begin
ExecuteAction(CurrentPackage,'fpmakeclean',Args);
Result:=true;
ExecuteAction(PackageName,'fpmakeclean');
end;
function TCommandArchive.Execute(const Args:TActionArgs):boolean;
procedure TCommandArchive.Execute;
begin
ExecuteAction(CurrentPackage,'fpmakearchive',Args);
Result:=true;
ExecuteAction(PackageName,'fpmakearchive');
end;
function TCommandInstallDependencies.Execute(const Args:TActionArgs):boolean;
procedure TCommandInstallDependencies.Execute;
var
i : Integer;
MissingDependency,
D : TFPDependency;
P,
DepPackage : TFPPackage;
InstalledP,
AvailP : TFPPackage;
L : TStringList;
status : string;
begin
if not assigned(CurrentPackage) then
if PackageName='' then
Error(SErrNoPackageSpecified);
// Load dependencies for local packages
if CurrentPackage.IsLocalPackage then
if IsLocalPackage then
begin
ExecuteAction(CurrentPackage,'fpmakemanifest',Args);
P:=LoadPackageManifest(ManifestFileName);
// Update CurrentPackage
CurrentPackage.Assign(P);
CurrentPackage.IsLocalPackage:=true;
end;
ExecuteAction(PackageName,'fpmakemanifest');
P:=LoadManifestFromFile(ManifestFileName);
end
else
P:=AvailableRepository.PackageByName(PackageName);
// Find and List dependencies
MissingDependency:=nil;
L:=TStringList.Create;
for i:=0 to CurrentPackage.Dependencies.Count-1 do
for i:=0 to P.Dependencies.Count-1 do
begin
D:=CurrentPackage.Dependencies[i];
D:=P.Dependencies[i];
if (CompilerOptions.CompilerOS in D.OSes) and
(CompilerOptions.CompilerCPU in D.CPUs) then
begin
DepPackage:=CurrentRepository.PackageByName(D.PackageName);
InstalledP:=InstalledRepository.FindPackage(D.PackageName);
// Need installation?
if (DepPackage.InstalledVersion.Empty) or
(DepPackage.InstalledVersion.CompareVersion(D.MinVersion)<0) then
if not assigned(InstalledP) or
(InstalledP.Version.CompareVersion(D.MinVersion)<0) then
begin
if DepPackage.Version.CompareVersion(D.MinVersion)<0 then
AvailP:=AvailableRepository.FindPackage(D.PackageName);
if not assigned(AvailP) or
(AvailP.Version.CompareVersion(D.MinVersion)<0) then
begin
status:='Not Available!';
MissingDependency:=D;
@ -333,21 +346,22 @@ begin
else
begin
status:='Updating';
L.Add(DepPackage.Name);
L.Add(D.PackageName);
end;
end
else
begin
if PackageIsBroken(DepPackage) then
if PackageIsBroken(InstalledP) then
begin
status:='Broken, recompiling';
L.Add(DepPackage.Name);
L.Add(D.PackageName);
end
else
status:='OK';
end;
Log(vlInfo,SLogPackageDependency,
[D.PackageName,D.MinVersion.AsString,DepPackage.InstalledVersion.AsString,DepPackage.Version.AsString,status]);
[D.PackageName,D.MinVersion.AsString,PackageInstalledVersionStr(D.PackageName),
PackageAvailableVersionStr(D.PackageName),status]);
end
else
Log(vlDebug,SDbgPackageDependencyOtherTarget,[D.PackageName,MakeTargetString(CompilerOptions.CompilerCPU,CompilerOptions.CompilerOS)]);
@ -357,19 +371,16 @@ begin
Error(SErrNoPackageAvailable,[MissingDependency.PackageName,MissingDependency.MinVersion.AsString]);
// Install needed updates
for i:=0 to L.Count-1 do
begin
DepPackage:=CurrentRepository.PackageByName(L[i]);
ExecuteAction(DepPackage,'install');
end;
ExecuteAction(L[i],'install');
FreeAndNil(L);
Result:=true;
if IsLocalPackage then
FreeAndNil(P);
end;
function TCommandFixBroken.Execute(const Args:TActionArgs):boolean;
procedure TCommandFixBroken.Execute;
var
i : integer;
P : TFPPackage;
SL : TStringList;
begin
SL:=TStringList.Create;
@ -379,13 +390,11 @@ begin
break;
for i:=0 to SL.Count-1 do
begin
P:=CurrentRepository.PackageByName(SL[i]);
ExecuteAction(P,'build');
ExecuteAction(P,'install');
ExecuteAction(SL[i],'build');
ExecuteAction(SL[i],'install');
end;
until false;
FreeAndNil(SL);
Result:=true;
end;

View File

@ -30,7 +30,7 @@ Type
TDownloadPackage = Class(TPackagehandler)
Public
Function Execute(const Args:TActionArgs):boolean;override;
Procedure Execute;override;
end;
procedure RegisterDownloader(const AName:string;Downloaderclass:TBaseDownloaderClass);
@ -44,9 +44,11 @@ implementation
uses
contnrs,
uriparser,
fprepos,
pkgglobals,
pkgoptions,
pkgmessages;
pkgmessages,
pkgrepos;
var
DownloaderList : TFPHashList;
@ -157,15 +159,17 @@ end;
{ TDownloadPackage }
function TDownloadPackage.Execute(const Args:TActionArgs):boolean;
procedure TDownloadPackage.Execute;
var
DownloaderClass : TBaseDownloaderClass;
P : TFPPackage;
begin
P:=AvailableRepository.PackageByName(PackageName);
DownloaderClass:=GetDownloader(GlobalOptions.Downloader);
with DownloaderClass.Create(nil) do
try
Log(vlCommands,SLogDownloading,[PackageRemoteArchive,PackageLocalArchive]);
Download(PackageRemoteArchive,PackageLocalArchive);
Log(vlCommands,SLogDownloading,[PackageRemoteArchive(P),PackageLocalArchive(P)]);
Download(PackageRemoteArchive(P),PackageLocalArchive(P));
finally
Free;
end;

View File

@ -13,16 +13,15 @@ uses
fprepos,
pkgoptions,
pkgglobals,
pkgmessages;
pkgmessages,
pkgrepos;
type
{ TFPMakeCompiler }
TFPMakeCompiler = Class(TPackagehandler)
Private
Procedure CompileFPMake;
Public
Function Execute(const Args:TActionArgs):boolean;override;
Procedure Execute;override;
end;
@ -38,7 +37,7 @@ type
TFPMakeRunnerCompile = Class(TFPMakeRunner)
Public
Function Execute(const Args:TActionArgs):boolean;override;
Procedure Execute;override;
end;
@ -46,7 +45,7 @@ type
TFPMakeRunnerBuild = Class(TFPMakeRunner)
Public
Function Execute(const Args:TActionArgs):boolean;override;
Procedure Execute;override;
end;
@ -54,7 +53,7 @@ type
TFPMakeRunnerInstall = Class(TFPMakeRunner)
Public
Function Execute(const Args:TActionArgs):boolean;override;
Procedure Execute;override;
end;
@ -62,21 +61,21 @@ type
TFPMakeRunnerClean = Class(TFPMakeRunner)
Public
Function Execute(const Args:TActionArgs):boolean;override;
Procedure Execute;override;
end;
{ TFPMakeRunnerManifest }
TFPMakeRunnerManifest = Class(TFPMakeRunner)
Public
Function Execute(const Args:TActionArgs):boolean;override;
Procedure Execute;override;
end;
{ TFPMakeRunnerArchive }
TFPMakeRunnerArchive = Class(TFPMakeRunner)
Public
Function Execute(const Args:TActionArgs):boolean;override;
Procedure Execute;override;
end;
TMyMemoryStream=class(TMemoryStream)
@ -120,7 +119,7 @@ end;
{ TFPMakeCompiler }
Procedure TFPMakeCompiler.CompileFPMake;
Procedure TFPMakeCompiler.Execute;
var
OOptions : string;
@ -161,9 +160,11 @@ Var
FPMakeSrc : string;
NeedFPMKUnitSource,
HaveFpmake : boolean;
P : TFPPackage;
begin
P:=InstalledRepository.PackageByName(PackageName);
OOptions:='';
SetCurrentDir(PackageBuildPath);
SetCurrentDir(PackageBuildPath(P));
// Check for fpmake source
FPMakeBin:='fpmake'+ExeExt;
FPMakeSrc:='fpmake.pp';
@ -236,18 +237,11 @@ begin
end;
function TFPMakeCompiler.Execute(const Args:TActionArgs):boolean;
begin
{$warning TODO Check arguments}
CompileFPMake;
result:=true;
end;
{ TFPMakeRunner }
Function TFPMakeRunner.RunFPMake(const Command:string) : Integer;
Var
P : TFPPackage;
FPMakeBin,
OOptions : string;
@ -261,15 +255,18 @@ Var
begin
OOptions:='';
// Does the current package support this CPU-OS?
if assigned(CurrentPackage) then
if PackageName<>'' then
P:=InstalledRepository.PackageByName(PackageName)
else
P:=nil;
if assigned(P) then
begin
if not(CompilerOptions.CompilerOS in CurrentPackage.OSes) or
not(CompilerOptions.CompilerCPU in CurrentPackage.CPUs) then
Error(SErrPackageDoesNotSupportTarget,[CurrentPackage.Name,
MakeTargetString(CompilerOptions.CompilerCPU,CompilerOptions.CompilerOS)]);
if not(CompilerOptions.CompilerOS in P.OSes) or
not(CompilerOptions.CompilerCPU in P.CPUs) then
Error(SErrPackageDoesNotSupportTarget,[P.Name,MakeTargetString(CompilerOptions.CompilerCPU,CompilerOptions.CompilerOS)]);
end;
{ Maybe compile fpmake executable? }
ExecuteAction(CurrentPackage,'compilefpmake');
ExecuteAction(PackageName,'compilefpmake');
{ Create options }
AddOption('--nofpccfg');
if vlInfo in LogLevels then
@ -286,51 +283,49 @@ begin
AddOption('--globalunitdir='+CompilerOptions.GlobalUnitDir);
{ Run FPMake }
FPMakeBin:='fpmake'+ExeExt;
SetCurrentDir(PackageBuildPath);
SetCurrentDir(PackageBuildPath(P));
Result:=ExecuteProcess(FPMakeBin,Command+' '+OOptions);
if Result<>0 then
Error(SErrExecutionFPMake,[Command]);
end;
function TFPMakeRunnerCompile.Execute(const Args:TActionArgs):boolean;
procedure TFPMakeRunnerCompile.Execute;
begin
result:=(RunFPMake('compile')=0);
RunFPMake('compile');
end;
function TFPMakeRunnerBuild.Execute(const Args:TActionArgs):boolean;
procedure TFPMakeRunnerBuild.Execute;
begin
result:=(RunFPMake('build')=0);
RunFPMake('build');
end;
function TFPMakeRunnerInstall.Execute(const Args:TActionArgs):boolean;
procedure TFPMakeRunnerInstall.Execute;
begin
result:=(RunFPMake('install')=0);
RunFPMake('install');
end;
function TFPMakeRunnerClean.Execute(const Args:TActionArgs):boolean;
procedure TFPMakeRunnerClean.Execute;
begin
result:=(RunFPMake('clean')=0);
RunFPMake('clean');
end;
function TFPMakeRunnerManifest.Execute(const Args:TActionArgs):boolean;
procedure TFPMakeRunnerManifest.Execute;
begin
result:=(RunFPMake('manifest')=0);
RunFPMake('manifest');
end;
function TFPMakeRunnerArchive.Execute(const Args:TActionArgs):boolean;
procedure TFPMakeRunnerArchive.Execute;
begin
result:=(RunFPMake('archive')=0);
RunFPMake('archive');
end;
initialization
RegisterPkgHandler('compilefpmake',TFPMakeCompiler);
RegisterPkgHandler('fpmakecompile',TFPMakeRunnerCompile);

View File

@ -10,52 +10,31 @@ uses
pkgoptions,
fprepos;
const
CmdLinePackageName='<cmdline>';
CurrentDirPackageName='<currentdir>';
type
{ TActionStack }
TActionArgs = array of string;
TActionStackItem = record
ActionPackage : TFPPackage;
Action : string;
Args : TActionArgs;
end;
PActionStackItem = ^TActionStackItem;
TActionStack = class
private
FList : TFPList;
public
constructor Create;
destructor Destroy;override;
procedure Push(APackage:TFPPackage;const AAction:string;const Args:TActionArgs);
procedure Push(APackage:TFPPackage;const AAction:string;const Args:array of string);
function Pop(out APackage:TFPPackage;out AAction:string;out Args:TActionArgs):boolean;
end;
{ TPackageHandler }
TPackageHandler = Class(TComponent)
private
FCurrentPackage : TFPPackage;
FPackageName : string;
FIsLocalPackage : boolean;
Protected
Procedure Log(Level: TLogLevel;Msg : String);
Procedure Log(Level: TLogLevel;Fmt : String; const Args : array of const);
Procedure Error(Msg : String);
Procedure Error(Fmt : String; const Args : array of const);
procedure ExecuteAction(APackage:TFPPackage;const AAction:string;const Args:TActionArgs=nil);
Function ExecuteProcess(Const Prog,Args:String):Integer;
Procedure SetCurrentDir(Const ADir:String);
function PackageBuildPath:String;
function PackageRemoteArchive:String;
function PackageLocalArchive:String;
function PackageManifestFile:String;
Public
Constructor Create(AOwner:TComponent;APackage:TFPPackage); virtual;
Constructor Create(AOwner:TComponent;const APackageName:string); virtual;
function PackageLogPrefix:String;
Function Execute(const Args:TActionArgs):boolean; virtual; abstract;
Property CurrentPackage:TFPPackage Read FCurrentPackage Write FCurrentPackage;
procedure ExecuteAction(const APackageName,AAction:string);
procedure Execute; virtual; abstract;
Property PackageName:string Read FPackageName;
Property IsLocalPackage:boolean Read FIsLocalPackage Write FIsLocalPackage;
end;
TPackageHandlerClass = class of TPackageHandler;
@ -64,7 +43,12 @@ type
// Actions/PkgHandler
procedure RegisterPkgHandler(const AAction:string;pkghandlerclass:TPackageHandlerClass);
function GetPkgHandler(const AAction:string):TPackageHandlerClass;
function ExecuteAction(APackage:TFPPackage;const AAction:string;const Args:TActionArgs=nil):Boolean;
procedure ExecuteAction(const APackageName,AAction:string);
function PackageBuildPath(APackage:TFPPackage):String;
function PackageRemoteArchive(APackage:TFPPackage): String;
function PackageLocalArchive(APackage:TFPPackage): String;
function PackageManifestFile(APackage:TFPPackage): String;
Implementation
@ -99,53 +83,83 @@ begin
end;
function ExecuteAction(APackage:TFPPackage;const AAction:string;const Args:TActionArgs=nil):Boolean;
procedure ExecuteAction(const APackageName,AAction:string);
var
pkghandlerclass : TPackageHandlerClass;
i : integer;
logargs : string;
FullActionName : string;
begin
result:=false;
// Check if we have already executed or are executing the action
if assigned(Apackage) then
FullActionName:=APackage.Name+AAction
else
FullActionName:=AAction;
FullActionName:=APackageName+AAction;
if ExecutedActions.Find(FullActionName)<>nil then
begin
Log(vlDebug,'Already executed or executing action '+FullActionName);
result:=true;
exit;
end;
ExecutedActions.Add(FullActionName,Pointer(PtrUInt(1)));
// Create action handler class
pkghandlerclass:=GetPkgHandler(AAction);
With pkghandlerclass.Create(nil,APackage) do
With pkghandlerclass.Create(nil,APackageName) do
try
logargs:='';
for i:=Low(Args) to High(Args) do
begin
if logargs='' then
logargs:=Args[i]
else
logargs:=logargs+','+Args[i];
end;
Log(vlDebug,SLogRunAction+' start',[AAction,logargs]);
result:=Execute(Args);
Log(vlDebug,SLogRunAction+' end',[AAction,logargs]);
if (APackageName=CmdLinePackageName) or
(APackageName=CurrentDirPackageName) then
IsLocalPackage:=true;
Log(vlDebug,SLogRunAction+' start',[AAction]);
Execute;
Log(vlDebug,SLogRunAction+' end',[AAction]);
finally
Free;
end;
end;
function PackageBuildPath(APackage:TFPPackage):String;
begin
if APackage.Name=CurrentDirPackageName then
Result:='.'
else if APackage.Name=CmdLinePackageName then
Result:=GlobalOptions.BuildDir+ChangeFileExt(ExtractFileName(APackage.LocalFileName),'')
else
Result:=GlobalOptions.BuildDir+APackage.Name;
end;
function PackageRemoteArchive(APackage:TFPPackage): String;
begin
if APackage.Name=CurrentDirPackageName then
Error(SErrNoPackageSpecified)
else if APackage.Name=CmdLinePackageName then
Error(SErrPackageIsLocal);
if APackage.ExternalURL<>'' then
Result:=APackage.ExternalURL
else
Result:=GetRemoteRepositoryURL(APackage.FileName);
end;
function PackageLocalArchive(APackage:TFPPackage): String;
begin
if APackage.Name=CurrentDirPackageName then
Error(SErrNoPackageSpecified)
else if APackage.Name=CmdLinePackageName then
Result:=APackage.LocalFileName
else
Result:=GlobalOptions.ArchivesDir+APackage.FileName;
end;
function PackageManifestFile(APackage:TFPPackage): String;
begin
Result:=ManifestFileName;
end;
{ TPackageHandler }
constructor TPackageHandler.Create(AOwner:TComponent;APackage:TFPPackage);
constructor TPackageHandler.Create(AOwner:TComponent;const APackageName:string);
begin
inherited Create(AOwner);
FCurrentPackage:=APackage;
FPackageName:=APackageName;
end;
Function TPackageHandler.ExecuteProcess(Const Prog,Args:String):Integer;
@ -163,53 +177,22 @@ begin
end;
function TPackageHandler.PackageBuildPath:String;
begin
if CurrentPackage=nil then
Result:='.'
else
Result:=GlobalOptions.BuildDir+CurrentPackage.Name;
end;
function TPackageHandler.PackageRemoteArchive: String;
begin
if not assigned(CurrentPackage) then
Error(SErrNoPackageSpecified);
if CurrentPackage.IsLocalPackage then
Error(SErrPackageIsLocal);
if CurrentPackage.ExternalURL<>'' then
Result:=CurrentPackage.ExternalURL
else
Result:=GetRemoteRepositoryURL(CurrentPackage.FileName);
end;
function TPackageHandler.PackageLocalArchive: String;
begin
if not assigned(CurrentPackage) then
Error(SErrNoPackageSpecified);
if CurrentPackage.IsLocalPackage then
Result:=CurrentPackage.FileName
else
Result:=GlobalOptions.ArchivesDir+CurrentPackage.FileName;
end;
function TPackageHandler.PackageManifestFile: String;
begin
Result:=ManifestFileName;
end;
function TPackageHandler.PackageLogPrefix:String;
begin
if assigned(CurrentPackage) then
Result:='['+CurrentPackage.Name+'] '
if PackageName<>'' then
Result:='['+PackageName+'] '
else
// Result:='[<currentdir>] ';
Result:='';
end;
procedure TPackageHandler.ExecuteAction(const APackageName,AAction:string);
begin
// Needed to override TComponent.ExecuteAction method
pkghandler.ExecuteAction(APackageName,AAction);
end;
Procedure TPackageHandler.Log(Level:TLogLevel; Msg:String);
begin
pkgglobals.Log(Level,PackageLogPrefix+Msg);
@ -234,71 +217,6 @@ begin
end;
procedure TPackageHandler.ExecuteAction(APackage: TFPPackage; const AAction: string; const Args: TActionArgs=nil);
begin
pkghandler.ExecuteAction(APackage,AAction,Args);
end;
{ TActionStack }
constructor TActionStack.Create;
begin
FList:=TFPList.Create;
end;
destructor TActionStack.Destroy;
begin
FreeAndNil(FList);
end;
procedure TActionStack.Push(APackage:TFPPackage;const AAction:string;const Args:TActionArgs);
var
ActionItem : PActionStackItem;
begin
New(ActionItem);
ActionItem^.ActionPackage:=APackage;
ActionItem^.Action:=AAction;
ActionItem^.Args:=Args;
FList.Add(ActionItem);
end;
procedure TActionStack.Push(APackage:TFPPackage;const AAction:string;const Args:array of string);
var
ActionArgs : TActionArgs;
i : integer;
begin
SetLength(ActionArgs,high(Args)+1);
for i:=low(Args) to high(Args) do
ActionArgs[i]:=Args[i];
Push(APackage,AAction,ActionArgs);
end;
function TActionStack.Pop(out APackage:TFPPackage;out AAction:string;out Args:TActionArgs):boolean;
var
ActionItem : PActionStackItem;
Idx : integer;
begin
Result:=false;
if FList.Count=0 then
exit;
// Retrieve Item from stack
Idx:=FList.Count-1;
ActionItem:=PActionStackItem(FList[Idx]);
FList.Delete(Idx);
// Copy contents and dispose stack item
APackage:=ActionItem^.ActionPackage;
AAction:=ActionItem^.Action;
Args:=ActionItem^.Args;
dispose(ActionItem);
Result:=true;
end;
initialization
PkgHandlerList:=TFPHashList.Create;
ExecutedActions:=TFPHashList.Create;

View File

@ -49,11 +49,12 @@ Resourcestring
SErrCWDFailed = 'FTP CWD "%s" command failed.';
SErrGETFailed = 'FTP GET "%s" command failed.';
SErrBrokenPackagesFound = 'Found broken packages, run "fppkg fixbroken" first';
SErrManifestNoSinglePackage = 'Manifest file "%s" does not contain exactly one package';
SLogGeneratingFPMake = 'Generating fpmake.pp';
SLogNotCompilingFPMake = 'Skipping compiling of fpmake.pp, fpmake executable already exists';
SLogCommandLineAction = 'Adding action from commandline: "%s %s"';
SLogRunAction = 'Action: "%s %s"';
SLogRunAction = 'Action: "%s"';
SLogExecute = 'Executing: "%s %s"';
SLogChangeDir = 'CurrentDir: "%s"';
SLogDownloading = 'Downloading "%s" to "%s"';

View File

@ -42,7 +42,7 @@ Type
procedure ConvertFile(const AFileName: String; Src: TStrings; Dir,OS : String);
Procedure ConvertFile(Const Source,Dest: String);
Public
Function Execute(const Args:TActionArgs):boolean;override;
Procedure Execute;override;
end;
@ -696,13 +696,12 @@ begin
end;
end;
function TMakeFileConverter.Execute(const Args:TActionArgs):boolean;
procedure TMakeFileConverter.Execute;
begin
if not FileExists('fpmake.pp') then
ConvertFile('Makefile.fpc','fpmake.pp')
else
Error(SErrConvertFPMakeExists);
result:=true;
end;
begin

View File

@ -10,24 +10,27 @@ uses
function GetRemoteRepositoryURL(const AFileName:string):string;
procedure LoadLocalMirrors;
procedure LoadLocalRepository;
function LoadOrCreatePackage(const AName:string):TFPPackage;
procedure LoadLocalAvailableMirrors;
procedure LoadLocalAvailableRepository;
procedure LoadUnitConfigFromFile(APackage:TFPPackage;const AFileName: String);
function LoadPackageManifest(const AManifestFN:string):TFPPackage;
function LoadManifestFromFile(const AManifestFN:string):TFPPackage;
procedure FindInstalledPackages(ACompilerOptions:TCompilerOptions;showdups:boolean=true);
function PackageIsBroken(APackage:TFPPackage):boolean;
function FindBrokenPackages(SL:TStrings):Boolean;
procedure CheckFPMakeDependencies;
procedure ListLocalRepository(all:boolean=false);
function PackageInstalledVersionStr(const AName:String):string;
function PackageAvailableVersionStr(const AName:String):string;
procedure ListAvailablePackages;
procedure ListInstalledPackages;
procedure ListRemoteRepository;
procedure RebuildRemoteRepository;
procedure SaveRemoteRepository;
var
CurrentMirrors : TFPMirrors;
CurrentRepository : TFPRepository;
AvailableMirrors : TFPMirrors;
AvailableRepository,
InstalledRepository : TFPRepository;
implementation
@ -45,14 +48,14 @@ uses
var
CurrentRemoteRepositoryURL : String;
procedure LoadLocalMirrors;
procedure LoadLocalAvailableMirrors;
var
S : String;
X : TFPXMLMirrorHandler;
begin
if assigned(CurrentMirrors) then
CurrentMirrors.Free;
CurrentMirrors:=TFPMirrors.Create(TFPMirror);
if assigned(AvailableMirrors) then
AvailableMirrors.Free;
AvailableMirrors:=TFPMirrors.Create(TFPMirror);
// Repository
S:=GlobalOptions.LocalMirrorsFile;
@ -63,7 +66,7 @@ begin
X:=TFPXMLMirrorHandler.Create;
With X do
try
LoadFromXml(CurrentMirrors,S);
LoadFromXml(AvailableMirrors,S);
finally
Free;
end;
@ -86,22 +89,22 @@ var
begin
Result:='';
M:=nil;
if assigned(CurrentMirrors) then
if assigned(AvailableMirrors) then
begin
// Create array for selection
BucketCnt:=0;
for i:=0 to CurrentMirrors.Count-1 do
inc(BucketCnt,CurrentMirrors[i].Weight);
for i:=0 to AvailableMirrors.Count-1 do
inc(BucketCnt,AvailableMirrors[i].Weight);
// Select random entry
Bucket:=Random(BucketCnt);
M:=nil;
for i:=0 to CurrentMirrors.Count-1 do
for i:=0 to AvailableMirrors.Count-1 do
begin
for j:=0 to CurrentMirrors[i].Weight-1 do
for j:=0 to AvailableMirrors[i].Weight-1 do
begin
if Bucket=0 then
begin
M:=CurrentMirrors[i];
M:=AvailableMirrors[i];
break;
end;
Dec(Bucket);
@ -163,55 +166,11 @@ begin
end;
procedure LoadLocalRepository;
var
S : String;
X : TFPXMLRepositoryHandler;
begin
if assigned(CurrentRepository) then
CurrentRepository.Free;
CurrentRepository:=TFPRepository.Create(Nil);
// Repository
S:=GlobalOptions.LocalPackagesFile;
Log(vlDebug,SLogLoadingPackagesFile,[S]);
if not FileExists(S) then
exit;
try
X:=TFPXMLRepositoryHandler.Create;
With X do
try
LoadFromXml(CurrentRepository,S);
finally
Free;
end;
except
on E : Exception do
begin
Log(vlError,E.Message);
Error(SErrCorruptPackagesFile,[S]);
end;
end;
end;
function LoadOrCreatePackage(const AName:string):TFPPackage;
begin
result:=CurrentRepository.FindPackage(AName);
if not assigned(result) then
begin
result:=CurrentRepository.AddPackage(AName);
result.IsLocalPackage:=true;
end;
end;
function LoadPackageManifest(const AManifestFN:string):TFPPackage;
function LoadManifestFromFile(const AManifestFN:string):TFPPackage;
var
X : TFPXMLRepositoryHandler;
i : integer;
DoAdd : Boolean;
NewP : TFPPackage;
NewPackages : TFPPackages;
NewP,P : TFPPackage;
begin
result:=nil;
NewPackages:=TFPPackages.Create(TFPPackage);
@ -219,27 +178,19 @@ begin
try
X.LoadFromXml(NewPackages,AManifestFN);
// Update or Add packages to repository
for i:=0 to NewPackages.Count-1 do
if NewPackages.Count=1 then
begin
NewP:=NewPackages[i];
DoAdd:=True;
result:=CurrentRepository.FindPackage(NewP.Name);
if assigned(result) then
begin
if NewP.Version.CompareVersion(result.Version)<0 then
begin
Writeln(Format('Ignoring package %s-%s (old %s)',[NewP.Name,NewP.Version.AsString,result.Version.AsString]));
DoAdd:=False;
end
else
Writeln(Format('Updating package %s-%s (old %s)',[NewP.Name,NewP.Version.AsString,result.Version.AsString]));
end
else
result:=CurrentRepository.PackageCollection.AddPackage(NewP.Name);
NewP:=NewPackages[0];
// Prevent duplicate names
{ P:=InstalledRepository.FindPackage(NewP.Name);
if not assigned(P) then
P:=InstalledRepository.AddPackage(NewP.Name); }
result:=TFPPackage.Create(nil);
// Copy contents
if DoAdd then
result.Assign(NewP);
end;
result.Assign(NewP);
end
else
Error(SErrManifestNoSinglePackage,[AManifestFN]);
finally
X.Free;
NewPackages.Free;
@ -262,12 +213,12 @@ begin
{$warning TODO Maybe check also CPU-OS}
// Read fpunits.conf
V:=L.Values['version'];
APackage.InstalledVersion.AsString:=V;
APackage.Version.AsString:=V;
V:=L.Values['checksum'];
if V<>'' then
APackage.InstalledChecksum:=StrToInt(V)
APackage.Checksum:=StrToInt(V)
else
APackage.InstalledChecksum:=$ffffffff;
APackage.Checksum:=$ffffffff;
// Load dependencies
V:=L.Values['depends'];
DepSL:=TStringList.Create;
@ -304,13 +255,16 @@ end;
procedure FindInstalledPackages(ACompilerOptions:TCompilerOptions;showdups:boolean=true);
procedure LogDuplicatePackages(APackage:TFPPackage;const AFileName: String);
function AddInstalledPackage(const AName,AFileName: String):TFPPackage;
begin
// Log packages found in multiple locations (local and global) ?
if not APackage.InstalledVersion.Empty then
result:=InstalledRepository.FindPackage(AName);
if not assigned(result) then
result:=InstalledRepository.AddPackage(AName)
else
begin
// Log packages found in multiple locations (local and global) ?
if showdups then
Log(vlDebug,SDbgPackageMultipleLocations,[APackage.Name,ExtractFilePath(AFileName)]);
Log(vlDebug,SDbgPackageMultipleLocations,[result.Name,ExtractFilePath(AFileName)]);
end;
end;
@ -323,7 +277,7 @@ procedure FindInstalledPackages(ACompilerOptions:TCompilerOptions;showdups:boole
Try
ReadIniFile(AFileName,L);
V:=L.Values['version'];
APackage.InstalledVersion.AsString:=V;
APackage.Version.AsString:=V;
Finally
L.Free;
end;
@ -347,8 +301,7 @@ procedure FindInstalledPackages(ACompilerOptions:TCompilerOptions;showdups:boole
UF:=UD+UnitConfigFileName;
if FileExistsLog(UF) then
begin
P:=LoadOrCreatePackage(SR.Name);
LogDuplicatePackages(P,UF);
P:=AddInstalledPackage(SR.Name,UF);
LoadUnitConfigFromFile(P,UF)
end
else
@ -357,8 +310,7 @@ procedure FindInstalledPackages(ACompilerOptions:TCompilerOptions;showdups:boole
UF:=UD+'Package.fpc';
if FileExistsLog(UF) then
begin
P:=LoadOrCreatePackage(SR.Name);
LogDuplicatePackages(P,UF);
P:=AddInstalledPackage(SR.Name,UF);
LoadPackagefpcFromFile(P,UF);
end;
end;
@ -368,7 +320,9 @@ procedure FindInstalledPackages(ACompilerOptions:TCompilerOptions;showdups:boole
end;
begin
CurrentRepository.ClearStatus;
if assigned(InstalledRepository) then
InstalledRepository.Free;
InstalledRepository:=TFPRepository.Create(nil);
// First scan the global directory
// The local directory will overwrite the versions
if ACompilerOptions.GlobalUnitDir<>'' then
@ -391,11 +345,11 @@ begin
if (CompilerOptions.CompilerOS in D.OSes) and
(CompilerOptions.CompilerCPU in D.CPUs) then
begin
DepPackage:=CurrentRepository.FindPackage(D.PackageName);
DepPackage:=InstalledRepository.FindPackage(D.PackageName);
// Don't stop on missing dependencies
if assigned(DepPackage) then
begin
if (DepPackage.InstalledChecksum<>D.RequireChecksum) then
if (DepPackage.Checksum<>D.RequireChecksum) then
begin
Log(vlInfo,SLogPackageChecksumChanged,[APackage.Name,D.PackageName]);
result:=true;
@ -415,15 +369,11 @@ var
P : TFPPackage;
begin
SL.Clear;
for i:=0 to CurrentRepository.PackageCount-1 do
for i:=0 to InstalledRepository.PackageCount-1 do
begin
P:=CurrentRepository.Packages[i];
// Process only installed packages
if not P.InstalledVersion.Empty then
begin
if PackageIsBroken(P) then
SL.Add(P.Name);
end;
P:=InstalledRepository.Packages[i];
if PackageIsBroken(P) then
SL.Add(P.Name);
end;
Result:=(SL.Count>0);
end;
@ -432,7 +382,8 @@ end;
procedure CheckFPMakeDependencies;
var
i : Integer;
P : TFPPackage;
P,AvailP : TFPPackage;
AvailVerStr : string;
ReqVer : TFPVersion;
begin
// Reset availability
@ -445,13 +396,18 @@ begin
// Check for fpmkunit dependencies
for i:=1 to FPMKUnitDepCount do
begin
P:=CurrentRepository.FindPackage(FPMKUnitDeps[i].package);
P:=InstalledRepository.FindPackage(FPMKUnitDeps[i].package);
if P<>nil then
begin
AvailP:=AvailableRepository.FindPackage(FPMKUnitDeps[i].package);
if P<>nil then
AvailVerStr:=AvailP.Version.AsString
else
AvailVerStr:='<not available>';
ReqVer:=TFPVersion.Create;
ReqVer.AsString:=FPMKUnitDeps[i].ReqVer;
Log(vlDebug,SLogFPMKUnitDepVersion,[P.Name,ReqVer.AsString,P.InstalledVersion.AsString,P.Version.AsString]);
if ReqVer.CompareVersion(P.InstalledVersion)<=0 then
Log(vlDebug,SLogFPMKUnitDepVersion,[P.Name,ReqVer.AsString,P.Version.AsString,AvailVerStr]);
if ReqVer.CompareVersion(P.Version)<=0 then
FPMKUnitDepAvailable[i]:=true
else
Log(vlDebug,SLogFPMKUnitDepTooOld,[FPMKUnitDeps[i].package]);
@ -462,7 +418,91 @@ begin
end;
procedure ListLocalRepository(all:boolean=false);
{*****************************************************************************
Local Available Repository
*****************************************************************************}
procedure LoadLocalAvailableRepository;
var
S : String;
X : TFPXMLRepositoryHandler;
begin
if assigned(AvailableRepository) then
AvailableRepository.Free;
AvailableRepository:=TFPRepository.Create(Nil);
// Repository
S:=GlobalOptions.LocalPackagesFile;
Log(vlDebug,SLogLoadingPackagesFile,[S]);
if not FileExists(S) then
exit;
try
X:=TFPXMLRepositoryHandler.Create;
With X do
try
LoadFromXml(AvailableRepository,S);
finally
Free;
end;
except
on E : Exception do
begin
Log(vlError,E.Message);
Error(SErrCorruptPackagesFile,[S]);
end;
end;
end;
function PackageAvailableVersionStr(const AName:String):string;
var
P : TFPPackage;
begin
P:=InstalledRepository.FindPackage(AName);
if P<>nil then
result:=P.Version.AsString
else
result:='-';
end;
function PackageInstalledVersionStr(const AName:String):string;
var
P : TFPPackage;
begin
P:=InstalledRepository.FindPackage(AName);
if P<>nil then
result:=P.Version.AsString
else
result:='-';
end;
procedure ListAvailablePackages;
var
InstalledP,
AvailP : TFPPackage;
i : integer;
SL : TStringList;
begin
SL:=TStringList.Create;
SL.Sorted:=true;
for i:=0 to AvailableRepository.PackageCount-1 do
begin
AvailP:=AvailableRepository.Packages[i];
InstalledP:=InstalledRepository.FindPackage(AvailP.Name);
if not assigned(InstalledP) or
(AvailP.Version.CompareVersion(InstalledP.Version)>0) then
SL.Add(Format('%-20s %-12s %-12s',[AvailP.Name,PackageInstalledVersionStr(AvailP.Name),AvailP.Version.AsString]));
end;
Writeln(Format('%-20s %-12s %-12s',['Name','Installed','Available']));
for i:=0 to SL.Count-1 do
Writeln(SL[i]);
FreeAndNil(SL);
end;
procedure ListInstalledPackages;
var
P : TFPPackage;
i : integer;
@ -470,11 +510,10 @@ var
begin
SL:=TStringList.Create;
SL.Sorted:=true;
for i:=0 to CurrentRepository.PackageCount-1 do
for i:=0 to InstalledRepository.PackageCount-1 do
begin
P:=CurrentRepository.Packages[i];
if all or (P.Version.CompareVersion(P.InstalledVersion)>0) then
SL.Add(Format('%-20s %-12s %-12s',[P.Name,P.InstalledVersion.AsString,P.Version.AsString]));
P:=InstalledRepository.Packages[i];
SL.Add(Format('%-20s %-12s %-12s',[P.Name,P.Version.AsString,PackageAvailableVersionStr(P.Name)]));
end;
Writeln(Format('%-20s %-12s %-12s',['Name','Installed','Available']));
for i:=0 to SL.Count-1 do
@ -487,6 +526,7 @@ end;
Remote Repository
*****************************************************************************}
procedure ListRemoteRepository;
var
P : TFPPackage;
@ -495,9 +535,9 @@ var
begin
SL:=TStringList.Create;
SL.Sorted:=true;
for i:=0 to CurrentRepository.PackageCount-1 do
for i:=0 to InstalledRepository.PackageCount-1 do
begin
P:=CurrentRepository.Packages[i];
P:=InstalledRepository.Packages[i];
SL.Add(Format('%-20s %-12s %-20s',[P.Name,P.Version.AsString,P.FileName]));
end;
Writeln(Format('%-20s %-12s %-20s',['Name','Available','FileName']));
@ -509,14 +549,54 @@ end;
procedure RebuildRemoteRepository;
procedure LoadPackageManifest(const AManifestFN:string);
var
X : TFPXMLRepositoryHandler;
i : integer;
DoAdd : Boolean;
P,NewP : TFPPackage;
NewPackages : TFPPackages;
begin
NewPackages:=TFPPackages.Create(TFPPackage);
X:=TFPXMLRepositoryHandler.Create;
try
X.LoadFromXml(NewPackages,AManifestFN);
// Update or Add packages to repository
for i:=0 to NewPackages.Count-1 do
begin
NewP:=NewPackages[i];
DoAdd:=True;
P:=InstalledRepository.FindPackage(NewP.Name);
if assigned(P) then
begin
if NewP.Version.CompareVersion(P.Version)<0 then
begin
Writeln(Format('Ignoring package %s-%s (old %s)',[NewP.Name,NewP.Version.AsString,P.Version.AsString]));
DoAdd:=False;
end
else
Writeln(Format('Updating package %s-%s (old %s)',[NewP.Name,NewP.Version.AsString,P.Version.AsString]));
end
else
P:=InstalledRepository.PackageCollection.AddPackage(NewP.Name);
// Copy contents
if DoAdd then
P.Assign(NewP);
end;
finally
X.Free;
NewPackages.Free;
end;
end;
var
i : integer;
ArchiveSL : TStringList;
ManifestSL : TStringList;
begin
if assigned(CurrentRepository) then
CurrentRepository.Free;
CurrentRepository:=TFPRepository.Create(Nil);
if assigned(InstalledRepository) then
InstalledRepository.Free;
InstalledRepository:=TFPRepository.Create(Nil);
try
ManifestSL:=TStringList.Create;
ManifestSL.Add(ManifestFileName);
@ -564,7 +644,7 @@ begin
X:=TFPXMLRepositoryHandler.Create;
With X do
try
SaveToXml(CurrentRepository,'packages.xml');
SaveToXml(InstalledRepository,'packages.xml');
finally
Free;
end;