123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897 |
- {
- This file is part of the Free Pascal Utilities
- Copyright (c) 1999-2000 by the Free Pascal development team
- See the file COPYING.FPC, included in this distribution,
- for details about the copyright.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- **********************************************************************}
- {$mode objfpc}
- {$H+}
- unit fprepos;
- interface
- uses
- classes,sysutils,
- contnrs,
- streamcoll,
- fpmktype;
- Const
- StreamVersion : Integer = 1;
- StreamSignature = $FEEF;
- Type
- { TFPVersion }
- TFPVersion = Class(TPersistent)
- private
- FMajor: Word;
- FMinor: Word;
- FRelease: Word;
- FSuffix: string;
- function GetAsString: String;
- function GetEmpty: Boolean;
- procedure SetAsString(const AValue: String);
- Public
- Procedure Assign(Source : TPersistent); override;
- Property AsString : String Read GetAsString Write SetAsString;
- Function CompareVersion(AVersion : TFPVersion) : Integer;
- Function SameVersion(AVersion : TFPVersion) : Boolean;
- Property Empty : Boolean Read GetEmpty;
- Published
- Property Release : Word Read FRelease Write FRelease;
- Property Major : Word Read FMajor Write FMajor;
- Property Minor : Word Read FMinor Write FMinor;
- Property Suffix : string Read FSuffix Write FSuffix;
- end;
- { TFPDependency }
- TFPDependency = Class(TStreamCollectionItem)
- private
- FMinVersion: TFPVersion;
- FPackageName: String;
- procedure SetMinVersion(const AValue: TFPVersion);
- Public
- Constructor Create(ACollection : TCollection); override;
- Destructor Destroy; override;
- Procedure LoadFromStream(Stream : TStream; Streamversion : Integer); override;
- Procedure SaveToStream(Stream : TStream); override;
- Procedure Assign(Source : TPersistent); override;
- Published
- Property PackageName : String Read FPackageName Write FPackageName;
- Property MinVersion : TFPVersion Read FMinVersion Write SetMinVersion;
- end;
- { TFPDepencencies }
- { TFPDependencies }
- TFPDependencies = Class(TStreamCollection)
- private
- function GetDependency(Index : Integer): TFPDependency;
- procedure SetDependency(Index : Integer; const AValue: TFPDependency);
- public
- Function AddDependency(Const APackageName : String; AMinVersion : String = '') : TFPDependency;
- Property Dependencies[Index : Integer] : TFPDependency Read GetDependency Write SetDependency;default;
- end;
- { TFPPackage }
- TFPPackage = Class(TStreamCollectionItem)
- private
- FAuthor: String;
- FDescription: String;
- FEmail: String;
- FLicense: String;
- FName: String;
- FExternalURL: String;
- FFileName: String;
- FVersion: TFPVersion;
- FInstalledVersion: TFPVersion;
- FDependencies : TFPDependencies;
- FOSes : TOSES;
- FCPUs : TCPUS;
- function GetDependencies: TFPDependencies;
- function GetHasDependencies: Boolean;
- function GetFileName: String;
- procedure SetName(const AValue: String);
- procedure SetVersion(const AValue: TFPVersion);
- Protected
- Function CreateDependencies : TFPDependencies; virtual;
- Public
- Constructor Create(ACollection : TCollection); override;
- Destructor Destroy; override;
- 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;
- Property HasDependencies : Boolean Read GetHasDependencies;
- Property Dependencies : TFPDependencies Read GetDependencies;
- Published
- Property Name : String Read FName Write SetName;
- Property Author : String Read FAuthor Write FAuthor;
- Property Version : TFPVersion Read FVersion Write SetVersion;
- Property InstalledVersion : TFPVersion Read FInstalledVersion Write FInstalledVersion;
- Property License : String Read FLicense Write FLicense;
- Property Description : String Read FDescription Write FDescription;
- Property ExternalURL : String Read FExternalURL Write FExternalURL;
- Property FileName : String Read GetFileName Write FFileName;
- Property Email : String Read FEmail Write FEmail;
- Property OSes : TOSes Read FOSes Write FOses;
- Property CPUs : TCPUs Read FCPUs Write FCPUs;
- end;
- { TFPPackages }
- TFPPackages = Class(TStreamCollection)
- private
- FVersion : Integer;
- function GetPackage(Index : Integer): TFPPackage;
- procedure SetPackage(Index : Integer; const AValue: TFPPackage);
- Protected
- Function CurrentStreamVersion : Integer; override;
- Public
- Function IndexOfPackage(PackageName : String) : Integer;
- Function FindPackage(PackageName : String) : TFPPackage;
- Function PackageByName(PackageName : String) : TFPPackage;
- Function AddPackage(PackageName : string) : TFPPackage;
- Property StreamVersion : Integer Read FVersion Write FVersion;
- Property Packages [Index : Integer] : TFPPackage Read GetPackage Write SetPackage; default;
- end;
- { TFPRepository }
- TFPRepository = Class(TComponent)
- Private
- FMaxDependencyLevel : Integer;
- FBackUpFiles: Boolean;
- FFileName: String;
- FPackageCount: Integer;
- FPackages : TFPPackages;
- function GetPackage(Index : Integer): TFPPackage;
- function GetPackageCount: Integer;
- Protected
- Property PackageCollection : TFPPackages Read FPackages;
- procedure CreatePackages; virtual;
- Procedure BackupFile(AFileName : String); virtual;
- Procedure DoGetPackageDependencies(PackageName : String; List : TStringList; Level : Integer); virtual;
- Public
- Constructor Create(AOwner : TComponent); override;
- Destructor Destroy; override;
- // Loading and Saving repository. Own format.
- Procedure LoadFromStream(Stream : TStream); Virtual;
- Procedure SaveToStream(Stream : TStream); Virtual;
- Procedure LoadFromFile(AFileName : String);
- Procedure SaveToFile(AFileName : String);
- Procedure Save;
- // Loading and Saving version numbers: List of Name=Value pairs.
- Procedure LoadStatusFromStream(Stream : TStream); virtual;
- Procedure SaveStatusToStream(Stream : TStream; InstalledStatus : Boolean); virtual;
- Procedure LoadStatusFromFile(AFileName : String);
- Procedure SaveStatusToFile(AFileName : String; InstalledStatus : Boolean);
- // Package management
- Function IndexOfPackage(PackageName : String) : Integer;
- Function FindPackage(PackageName : String) : TFPPackage;
- Function PackageByName(PackageName : String) : TFPPackage;
- Procedure DeletePackage(Index : Integer);
- Procedure RemovePackage(PackageName : string);
- Function AddPackage(PackageName : string) : TFPPackage;
- // Dependencies
- Procedure GetPackageDependencies(PackageName : String; List : TObjectList; Recurse : Boolean);
- // Properties
- Property FileName : String Read FFileName;
- Property Packages[Index : Integer] : TFPPackage Read GetPackage; default;
- Property PackageCount : Integer Read GetPackageCount;
- Property BackupFiles : Boolean Read FBackUpFiles Write FBackupFiles;
- Property MaxDependencyLevel : Integer Read FMaxDependencyLevel Write FMaxDependencyLevel;
- end;
- EPackage = Class(Exception);
- Const
- // Max level of dependency searching before we decide it's a circular dependency.
- DefaultMaxDependencyLevel = 15;
- Implementation
- uses
- typinfo,
- uriparser;
- ResourceString
- SErrPackageNotFound = 'Package "%s" not found.';
- SErrInvalidRepositorySig = 'Invalid repository stream. Stream signature incorrect';
- SErrBackupFailed = 'Failed to back up file "%s" to "%s".';
- SErrNoFileName = 'No filename for repository specified.';
- SErrDuplicatePackageName = 'Duplicate package name : "%s"';
- SErrMaxLevelExceeded = 'Maximum number of dependency levels exceeded (%d) at package "%s".';
- { TFPVersion }
- function TFPVersion.GetAsString: String;
- begin
- Result:=Format('%d.%d.%d',[Release,Major,Minor]);
- If (Suffix<>'') then
- Result:=Result+'-'+Suffix;
- end;
- function TFPVersion.GetEmpty: Boolean;
- begin
- Result:=(Release=0) and (Major=0) and (Minor=0) and (Suffix='');
- end;
- procedure TFPVersion.SetAsString(const AValue: String);
- Function NextDigit(sep : Char; var V : string) : integer;
- Var
- P : Integer;
- begin
- P:=Pos(Sep,V);
- If (P=0) then
- P:=Length(V)+1;
- Result:=StrToIntDef(Copy(V,1,P-1),-1);
- If Result<>-1 then
- Delete(V,1,P)
- else
- Result:=0;
- end;
- Var
- P : Integer;
- V : String;
- begin
- Release:=0;
- Major:=0;
- Minor:=0;
- Suffix:='';
- V:=AValue;
- Release:=NextDigit('.',V);
- Major:=NextDigit('.',V);
- Minor:=NextDigit('-',V);
- P:=Pos('-',V);
- If (P<>0) then
- Delete(V,1,P);
- Suffix:=V;
- end;
- procedure TFPVersion.Assign(Source: TPersistent);
- Var
- V : TFPVersion;
- begin
- if Source is TFPVersion then
- begin
- V:=Source as TFPVersion;
- Release:=V.Release;
- Major:=V.Major;
- Minor:=V.Minor;
- Suffix:=V.Suffix;
- end
- else
- inherited Assign(Source);
- end;
- function TFPVersion.CompareVersion(AVersion: TFPVersion): Integer;
- begin
- Result:=Release-AVersion.Release;
- If (Result=0) then
- begin
- Result:=Major-AVersion.Major;
- if (Result=0) then
- begin
- Result:=Minor-AVersion.Minor;
- If (Result=0) then
- Result:=CompareText(Suffix,AVersion.Suffix);
- end;
- end;
- end;
- function TFPVersion.SameVersion(AVersion: TFPVersion): Boolean;
- begin
- Result:=CompareVersion(AVersion)=0;
- end;
- { TFPPackage }
- procedure TFPPackage.SetVersion(const AValue: TFPVersion);
- begin
- if FVersion=AValue then
- exit;
- FVersion.Assign(AValue);
- end;
- Function TFPPackage.CreateDependencies : TFPDependencies;
- begin
- Result:=TFPDependencies.Create(TFPDependency);
- end;
- constructor TFPPackage.Create(ACollection: TCollection);
- begin
- inherited Create(ACollection);
- FVersion:=TFPVersion.Create;
- FInstalledVersion:=TFPVersion.Create;
- end;
- destructor TFPPackage.Destroy;
- begin
- FreeAndNil(FDependencies);
- FreeAndNil(FVersion);
- FreeAndNil(FInstalledVersion);
- inherited Destroy;
- end;
- procedure TFPPackage.SetName(const AValue: String);
- Var
- I : Integer;
- begin
- If (AValue<>FName) and (AValue<>'') then
- If (Collection<>Nil) and (Collection is TFPPackages) then
- // do not check while loading, this would slow down a lot !!
- if (not TFPPackages(Collection).Streaming) then
- If TFPPackages(Collection).IndexOfPackage(AValue)<>-1 then
- Raise EPackage.CreateFmt(SErrDuplicatePackageName,[AValue]);
- FName:=AValue;
- end;
- function TFPPackage.GetDependencies: TFPDependencies;
- begin
- If Not Assigned(FDependencies) then
- FDependencies:=CreateDependencies;
- Result:=FDependencies;
- end;
- function TFPPackage.GetHasDependencies: Boolean;
- begin
- Result:=Assigned(FDependencies) and (FDependencies.Count>0);
- end;
- function TFPPackage.GetFileName: String;
- var
- URI : TURI;
- begin
- if FFileName='' then
- begin
- URI:=ParseURI(ExternalURL);
- Result:=URI.Document;
- end
- else
- Result:=FFileName;
- end;
- procedure TFPPackage.LoadFromStream(Stream: TStream; Streamversion : Integer);
- Var
- B : Boolean;
- O : TOSes;
- C : TCPUs;
- I,J,Count : Integer;
- begin
- Version.AsString:=ReadString(Stream);
- Name:=ReadString(Stream);
- Author:=ReadString(Stream);
- License:=ReadString(Stream);
- Description:=ReadString(Stream);
- ExternalURL:=ReadString(Stream);
- FileName:=ReadString(Stream);
- Email:=ReadString(Stream);
- Count:=ReadInteger(Stream);
- O:=[];
- For I:=1 to Count do
- begin
- J:=GetEnumValue(TypeInfo(TOS),ReadString(Stream));
- If (J<>-1) then
- Include(O,TOS(J));
- end;
- OSEs:=O;
- Count:=ReadInteger(Stream);
- C:=[];
- For I:=1 to Count do
- begin
- J:=GetEnumValue(TypeInfo(TCPU),ReadString(Stream));
- If (J<>-1) then
- Include(C,TCPU(J));
- end;
- CPUS:=C;
- FreeAndNil(FDependencies);
- B:=ReadBoolean(Stream);
- If B then
- begin
- FDependencies:=CreateDependencies;
- FDependencies.LoadFromStream(Stream);
- end
- end;
- procedure TFPPackage.SaveToStream(Stream: TStream);
- Var
- Count : Integer;
- O : TOS;
- C : TCPU;
- begin
- WriteString(Stream,Version.AsString);
- WriteString(Stream,Name);
- WriteString(Stream,Author);
- WriteString(Stream,License);
- WriteString(Stream,Description);
- WriteString(Stream,ExternalURL);
- WriteString(Stream,FileName);
- WriteString(Stream,Email);
- { Write it like this, makes error checking easier when reading. }
- // OSes
- Count:=0;
- For O:=Low(TOS) to High(TOS) do
- If O in OSes then
- Inc(Count);
- WriteInteger(Stream,Count);
- For O:=Low(TOS) to High(TOS) do
- If O in OSes then
- WriteString(Stream,GetEnumName(TypeInfo(TOS),Ord(O)));
- // CPUs
- Count:=0;
- For C:=Low(TCPU) to High(TCPU) do
- If C in CPUS then
- Inc(Count);
- WriteInteger(Stream,Count);
- For C:=Low(TCPU) to High(TCPU) do
- If C in CPUS then
- WriteString(Stream,GetEnumName(TypeInfo(TCPU),Ord(C)));
- WriteBoolean(Stream,HasDependencies);
- If HasDependencies then
- FDependencies.SaveToStream(Stream);
- end;
- procedure TFPPackage.Assign(Source: TPersistent);
- Var
- P : TFPPackage;
- begin
- if Source is TFPPackage then
- begin
- P:=Source as TFPPackage;
- // This creates trouble if P has the same owning collection !!
- If P.Collection<>Collection then
- Name:=P.Name;
- Author:=P.Author;
- Version:=P.Version;
- Description:=P.Description;
- ExternalURL:=P.ExternalURL;
- FileName:=P.FileName;
- InstalledVersion:=P.Installedversion;
- If P.HasDependencies then
- Dependencies.Assign(P.Dependencies)
- else
- FreeAndNil(FDependencies);
- end
- else
- inherited Assign(Source);
- end;
- function TFPPackage.AddDependency(const APackageName: String;
- AMinVersion: String): TFPDependency;
- begin
- Result:=Dependencies.AddDependency(APackageName,AMinVersion);
- end;
- { TFPPackages }
- function TFPPackages.GetPackage(Index : Integer): TFPPackage;
- begin
- Result:=TFPPackage(Items[Index])
- end;
- procedure TFPPackages.SetPackage(Index : Integer; const AValue: TFPPackage);
- begin
- Items[Index]:=AValue;
- end;
- function TFPPackages.CurrentStreamVersion: Integer;
- begin
- Result:=FVersion;
- end;
- function TFPPackages.IndexOfPackage(PackageName: String): Integer;
- begin
- Result:=Count-1;
- While (Result>=0) and (CompareText(GetPackage(Result).Name,PackageName)<>0) do
- Dec(Result);
- end;
- function TFPPackages.FindPackage(PackageName: String): TFPPackage;
- Var
- I : Integer;
- begin
- I:=IndexOfPackage(PackageName);
- If (I=-1) then
- Result:=Nil
- else
- Result:=GetPackage(I);
- end;
- function TFPPackages.PackageByName(PackageName: String): TFPPackage;
- begin
- Result:=FindPackage(PackageName);
- If Result=Nil then
- Raise EPackage.CreateFmt(SErrPackageNotFound,[PackageName]);
- end;
- function TFPPackages.AddPackage(PackageName: string): TFPPackage;
- begin
- Result:=Add as TFPPackage;
- Try
- Result.Name:=PackageName;
- Except
- Result.Free;
- Raise;
- end;
- end;
- { TFPRepository }
- function TFPRepository.GetPackage(Index : Integer): TFPPackage;
- begin
- Result:=FPackages[Index];
- end;
- function TFPRepository.GetPackageCount: Integer;
- begin
- Result:=FPackages.Count;
- end;
- constructor TFPRepository.Create(AOwner: TComponent);
- begin
- inherited Create(AOwner);
- CreatePackages;
- FMaxDependencyLevel:=DefaultMaxDependencyLevel;
- end;
- procedure TFPRepository.CreatePackages;
- begin
- FPackages:=TFPPackages.Create(TFPPackage);
- FPackages.StreamVersion:=StreamVersion;
- end;
- procedure TFPRepository.BackupFile(AFileName: String);
- Var
- S : String;
- begin
- S:=AFileName+'.bak';
- if not RenameFile(AFileName,S) then
- Raise EPackage.CreateFmt(SErrBackupFailed,[AFileName,S]);
- end;
- destructor TFPRepository.Destroy;
- begin
- FreeAndNil(FPackages);
- inherited Destroy;
- end;
- procedure TFPRepository.LoadFromStream(Stream: TStream);
- Var
- I : Integer;
- V : Integer;
- begin
- Stream.ReadBuffer(I,SizeOf(Integer));
- If (I<>StreamSignature) then
- Raise EPackage.Create(SErrInvalidRepositorySig);
- Stream.ReadBuffer(V,SizeOf(V));
- FPackages.LoadFromStream(Stream);
- end;
- procedure TFPRepository.SaveToStream(Stream: TStream);
- Var
- i : Integer;
- begin
- I:=StreamSignature;
- Stream.WriteBuffer(I,SizeOf(Integer));
- I:=StreamVersion;
- Stream.WriteBuffer(I,SizeOf(Integer));
- FPackages.SaveToStream(Stream);
- end;
- procedure TFPRepository.LoadFromFile(AFileName: String);
- Var
- F : TFileStream;
- begin
- F:=TFileStream.Create(AFileName,fmopenRead);
- Try
- LoadFromStream(F);
- FFileName:=AFileName;
- Finally
- F.Free;
- end;
- end;
- procedure TFPRepository.SaveToFile(AFileName: String);
- Var
- F : TFileStream;
- S : String;
- begin
- If FileExists(AFileName) and BackupFiles then
- BackupFile(AFileName);
- F:=TFileStream.Create(AFileName,fmCreate);
- Try
- SaveToStream(F);
- FFileName:=AFileName;
- Finally
- F.Free;
- end;
- end;
- procedure TFPRepository.Save;
- begin
- If (FFileName='') then
- Raise EPackage.Create(SErrNoFileName);
- SaveToFile(FFileName);
- end;
- 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;InstalledStatus : Boolean);
- Var
- L : TStrings;
- I : Integer;
- begin
- L:=TStringList.Create;
- Try
- If InstalledStatus then
- For I:=0 to PackageCount-1 do
- With Packages[i] do
- L.Add(Name+'='+InstalledVersion.AsString)
- else
- For I:=0 to PackageCount-1 do
- With Packages[i] do
- L.Add(Name+'='+Version.AsString);
- L.SaveToStream(Stream);
- Finally
- L.Free;
- end;
- end;
- procedure TFPRepository.LoadStatusFromFile(AFileName: String);
- Var
- F : TFileStream;
- begin
- F:=TFileStream.Create(AFileName,fmOpenRead);
- Try
- LoadStatusFromStream(F);
- Finally
- F.Free;
- end;
- end;
- procedure TFPRepository.SaveStatusToFile(AFileName: String; InstalledStatus : Boolean);
- Var
- F : TFileStream;
- begin
- If FileExists(AFileName) and BackupFiles then
- BackupFile(AFileName);
- F:=TFileStream.Create(AFileName,fmCreate);
- Try
- SaveStatusToStream(F,InstalledStatus);
- Finally
- F.Free;
- end;
- end;
- function TFPRepository.IndexOfPackage(PackageName: String): Integer;
- begin
- Result:=FPackages.IndexOfPackage(PackageName);
- end;
- function TFPRepository.FindPackage(PackageName: String): TFPPackage;
- begin
- Result:=FPackages.FindPackage(PackageName);
- end;
- function TFPRepository.PackageByName(PackageName: String): TFPPackage;
- begin
- Result:=FPackages.PackageByName(PackageName);
- end;
- procedure TFPRepository.RemovePackage(PackageName: string);
- begin
- PackageByName(PackageName).Free;
- end;
- procedure TFPRepository.DeletePackage(Index : Integer);
- begin
- GetPackage(Index).Free;
- end;
- function TFPRepository.AddPackage(PackageName: string): TFPPackage;
- begin
- Result:=FPackages.AddPackage(PackageName);
- end;
- procedure TFPRepository.DoGetPackageDependencies(PackageName: String;
- List: TStringList; Level: Integer);
- Var
- P : TFPPackage;
- D2,D1 : TFPDependency;
- i,J : Integer;
- begin
- // If too many levels, bail out
- If (Level>FMaxDependencyLevel) then
- Raise EPackage.CreateFmt(SErrMaxLevelExceeded,[Level,PackageName]);
- // Check if it is a known package.
- P:=FindPackage(PackageName);
- If Assigned(P) and P.HasDependencies then
- For I:=0 to P.Dependencies.Count-1 do
- begin
- D1:=P.Dependencies[i];
- J:=List.IndexOf(PackageName);
- If J=-1 then
- begin
- // Dependency not yet in list.
- D2:=TFPDependency.Create(Nil);
- D2.Assign(D1);
- List.AddObject(D2.PackageName,D2);
- end
- else
- begin
- // Dependency already in list, compare versions.
- D2:=List.Objects[J] as TFPDependency;
- If D1.MinVersion.CompareVersion(D2.MinVersion)>0 then
- D2.MinVersion.Assign(D1.MinVersion);
- end;
- // If it was already in the list, we no longer recurse.
- If (Level>=0) and (J=-1) Then
- DoGetPackageDependencies(D2.PackageName,List,Level+1);
- end;
- end;
- procedure TFPRepository.GetPackageDependencies(PackageName: String;
- List: TObjectList; Recurse: Boolean);
- Var
- L : TStringList;
- I : Integer;
- begin
- L:=TStringList.Create;
- Try
- L.Sorted:=True;
- DoGetPackageDependencies(PackageName,L,Ord(Recurse)-1);
- For I:=0 to L.Count-1 do
- List.Add(L.Objects[i]);
- Finally
- // Freeing a stringlist does not free the objects.
- L.Free;
- end;
- end;
- { TFPDependency }
- procedure TFPDependency.SetMinVersion(const AValue: TFPVersion);
- begin
- FMinVersion.Assign(AValue);
- end;
- constructor TFPDependency.Create(ACollection: TCollection);
- begin
- inherited Create(ACollection);
- FMinVersion:=TFPVersion.Create;
- end;
- destructor TFPDependency.Destroy;
- begin
- FreeAndNil(FMinVersion);
- inherited Destroy;
- end;
- procedure TFPDependency.LoadFromStream(Stream: TStream; Streamversion: Integer
- );
- begin
- PackageName:=ReadString(Stream);
- MinVersion.AsString:=ReadString(Stream)
- end;
- procedure TFPDependency.SaveToStream(Stream: TStream);
- begin
- WriteString(Stream,PackageName);
- WriteString(Stream,MinVersion.AsString);
- end;
- procedure TFPDependency.Assign(Source: TPersistent);
- begin
- If Source is TFPDependency then
- With Source as TFPDependency do
- begin
- Self.PackageName:=PackageName;
- Self.MinVersion:=MinVersion;
- end
- else
- inherited Assign(Source);
- end;
- { TFPDependencies }
- function TFPDependencies.GetDependency(Index : Integer): TFPDependency;
- begin
- Result:=TFPDependency(Items[Index]);
- end;
- procedure TFPDependencies.SetDependency(Index : Integer;
- const AValue: TFPDependency);
- begin
- Items[Index]:=AValue;
- end;
- function TFPDependencies.AddDependency(const APackageName: String;
- AMinVersion: String): TFPDependency;
- begin
- Result:=Add as TFPDependency;
- Result.PackageName:=APackageName;
- If (AMinVersion<>'') then
- Result.MinVersion.AsString:=AMinVersion;
- end;
- end.
|