diff --git a/utils/fppkg/fppkg.pp b/utils/fppkg/fppkg.pp index baca2cca64..76759b882d 100644 --- a/utils/fppkg/fppkg.pp +++ b/utils/fppkg/fppkg.pp @@ -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,['[]',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; diff --git a/utils/fppkg/fprepos.pp b/utils/fppkg/fprepos.pp index 11b025d349..b9d255260a 100644 --- a/utils/fppkg/fprepos.pp +++ b/utils/fppkg/fprepos.pp @@ -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); diff --git a/utils/fppkg/pkgcommands.pp b/utils/fppkg/pkgcommands.pp index d4f4a7844d..4bb8479749 100644 --- a/utils/fppkg/pkgcommands.pp +++ b/utils/fppkg/pkgcommands.pp @@ -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; diff --git a/utils/fppkg/pkgdownload.pp b/utils/fppkg/pkgdownload.pp index 1ee15d1213..0fef1e2843 100644 --- a/utils/fppkg/pkgdownload.pp +++ b/utils/fppkg/pkgdownload.pp @@ -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; diff --git a/utils/fppkg/pkgfpmake.pp b/utils/fppkg/pkgfpmake.pp index f13aff88d2..5d7b13767e 100644 --- a/utils/fppkg/pkgfpmake.pp +++ b/utils/fppkg/pkgfpmake.pp @@ -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); diff --git a/utils/fppkg/pkghandler.pp b/utils/fppkg/pkghandler.pp index 104f752171..fc556389fe 100644 --- a/utils/fppkg/pkghandler.pp +++ b/utils/fppkg/pkghandler.pp @@ -10,52 +10,31 @@ uses pkgoptions, fprepos; +const + CmdLinePackageName=''; + CurrentDirPackageName=''; + 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:='[] '; 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; diff --git a/utils/fppkg/pkgmessages.pp b/utils/fppkg/pkgmessages.pp index 278a3148bc..51233e56e3 100644 --- a/utils/fppkg/pkgmessages.pp +++ b/utils/fppkg/pkgmessages.pp @@ -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"'; diff --git a/utils/fppkg/pkgmkconv.pp b/utils/fppkg/pkgmkconv.pp index 4b2600471e..e54fa674b1 100644 --- a/utils/fppkg/pkgmkconv.pp +++ b/utils/fppkg/pkgmkconv.pp @@ -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 diff --git a/utils/fppkg/pkgrepos.pp b/utils/fppkg/pkgrepos.pp index b89ddf1a87..af0d734db7 100644 --- a/utils/fppkg/pkgrepos.pp +++ b/utils/fppkg/pkgrepos.pp @@ -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:=''; 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;