Prechádzať zdrojové kódy

* recovery mode added to always use internal fpmkunit
* fix dependency versioning

git-svn-id: trunk@10280 -

peter 17 rokov pred
rodič
commit
36316bea75

Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 142 - 142
utils/fppkg/fpmkunitsrc.inc


+ 11 - 6
utils/fppkg/fppkg.pp

@@ -154,6 +154,7 @@ begin
   Writeln('  -d --debug         Show debugging information');
   Writeln('  -g --global        Force installation to global (system-wide) directory');
   Writeln('  -f --force         Force installation also if the package is already installed');
+  Writeln('  -r --recovery      Recovery mode, use always internal fpmkunit');
   Writeln('Actions:');
   Writeln('  update             Update packages list');
   Writeln('  showavail          List available packages');
@@ -242,6 +243,8 @@ begin
         LogLevels:=AllLogLevels+[vlDebug]
       else if CheckOption(I,'g','global') then
         GlobalOptions.InstallGlobal:=true
+      else if CheckOption(I,'r','recovery') then
+        GlobalOptions.RecoveryMode:=true
       else if CheckOption(I,'h','help') then
         begin
           ShowUsage;
@@ -313,16 +316,18 @@ begin
           begin
             if FileExists(ParaPackages[i]) then
               begin
-                ActionPackage:=CurrentRepository.AddPackage(ChangeFileExt(ExtractFileName(ParaPackages[i]),''));
+                ActionPackage:=LoadOrCreatePackage(ChangeFileExt(ExtractFileName(ParaPackages[i]),''));
                 ActionPackage.FileName:=ExpandFileName(ParaPackages[i]);
                 ActionPackage.IsLocalPackage:=true;
+                res:=pkghandler.ExecuteAction(ActionPackage,ParaAction);
+                FreeAndNil(ActionPackage);
               end
             else
-              ActionPackage:=CurrentRepository.PackageByName(ParaPackages[i]);
-            Log(vlDebug,SLogCommandLineAction,['['+ActionPackage.Name+']',ParaAction]);
-            res:=pkghandler.ExecuteAction(ActionPackage,ParaAction);
-            if ActionPackage.IsLocalPackage then;
-              FreeAndNil(ActionPackage);
+              begin
+                ActionPackage:=CurrentRepository.PackageByName(ParaPackages[i]);
+                Log(vlDebug,SLogCommandLineAction,['['+ActionPackage.Name+']',ParaAction]);
+                res:=pkghandler.ExecuteAction(ActionPackage,ParaAction);
+              end;
             if not res then
               break;
           end;

+ 98 - 114
utils/fppkg/fprepos.pp

@@ -121,13 +121,9 @@ type
     FOSes : TOSES;
     FCPUs : TCPUS;
     FIsLocalPackage : Boolean;
-    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;
@@ -135,8 +131,7 @@ type
     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;
+    Property Dependencies : TFPDependencies Read FDependencies;
   Published
     Property Name : String Read FName Write SetName;
     Property Author : String Read FAuthor Write FAuthor;
@@ -196,10 +191,12 @@ type
     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;
@@ -298,34 +295,32 @@ ResourceString
 
 
 Function OSToString(OS: TOS) : String;
-
 begin
   Result:=LowerCase(GetenumName(TypeInfo(TOS),Ord(OS)));
 end;
 
-Function OSesToString(OSes: TOSes) : String;
 
+Function OSesToString(OSes: TOSes) : String;
 begin
   Result:=LowerCase(SetToString(PtypeInfo(TypeInfo(TOSes)),Integer(OSes),False));
 end;
 
-Function CPUToString(CPU: TCPU) : String;
 
+Function CPUToString(CPU: TCPU) : String;
 begin
   Result:=LowerCase(GetenumName(TypeInfo(TCPU),Ord(CPU)));
 end;
 
-Function CPUSToString(CPUS: TCPUS) : String;
 
+Function CPUSToString(CPUS: TCPUS) : String;
 begin
   Result:=LowerCase(SetToString(PTypeInfo(TypeInfo(TCPUS)),Integer(CPUS),False));
 end;
 
-Function StringToOS(S : String) : TOS;
 
+Function StringToOS(S : String) : TOS;
 Var
   I : Integer;
-
 begin
   I:=GetEnumValue(TypeInfo(TOS),S);
   if (I=-1) then
@@ -335,16 +330,14 @@ end;
 
 
 Function OSesToString(S : String) : TOSes;
-
 begin
   Result:=TOSes(StringToSet(PTypeInfo(TypeInfo(TOSes)),S));
 end;
 
-Function StringToCPU(S : String) : TCPU;
 
+Function StringToCPU(S : String) : TCPU;
 Var
   I : Integer;
-
 begin
   I:=GetEnumValue(TypeInfo(TCPU),S);
   if (I=-1) then
@@ -352,23 +345,22 @@ begin
   Result:=TCPU(I);
 end;
 
-Function StringToCPUS(S : String) : TCPUS;
 
+Function StringToCPUS(S : String) : TCPUS;
 begin
   Result:=TCPUS(StringToSet(PTypeInfo(TypeInfo(TCPUS)),S));
 end;
 
-Function MakeTargetString(CPU : TCPU;OS: TOS) : String;
 
+Function MakeTargetString(CPU : TCPU;OS: TOS) : String;
 begin
   Result:=CPUToString(CPU)+'-'+OSToString(OS);
 end;
 
-Procedure StringToCPUOS(S : String; Var CPU : TCPU; Var OS: TOS);
 
+Procedure StringToCPUOS(S : String; Var CPU : TCPU; Var OS: TOS);
 Var
   P : integer;
-
 begin
   P:=Pos('-',S);
   If (P=0) then
@@ -388,18 +380,18 @@ begin
     Result:=Format('%d.%d.%d-%d',[Major,Minor,Micro,Build]);
 end;
 
+
 function TFPVersion.GetEmpty: Boolean;
 begin
   Result:=(Major=0) and (Minor=0) and (Micro=0) and (Build=0);
 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
@@ -425,6 +417,7 @@ begin
   Build:=NextDigit(#0,V);
 end;
 
+
 procedure TFPVersion.Clear;
 begin
   Micro:=0;
@@ -433,24 +426,24 @@ begin
   Build:=0;
 end;
 
-procedure TFPVersion.Assign(Source: TPersistent);
 
+procedure TFPVersion.Assign(Source: TPersistent);
 Var
   V : TFPVersion;
-
 begin
   if Source is TFPVersion then
     begin
-    V:=Source as TFPVersion;
-    Major:=V.Major;
-    Minor:=V.Minor;
-    Micro:=V.Micro;
-    Build:=V.Build;
+      V:=Source as TFPVersion;
+      Major:=V.Major;
+      Minor:=V.Minor;
+      Micro:=V.Micro;
+      Build:=V.Build;
     end
   else
     inherited Assign(Source);
 end;
 
+
 function TFPVersion.CompareVersion(AVersion: TFPVersion): Integer;
 begin
   Result:=Major-AVersion.Major;
@@ -466,6 +459,7 @@ begin
     end;
 end;
 
+
 function TFPVersion.SameVersion(AVersion: TFPVersion): Boolean;
 begin
   Result:=CompareVersion(AVersion)=0;
@@ -480,10 +474,6 @@ begin
   FVersion.Assign(AValue);
 end;
 
-Function TFPPackage.CreateDependencies : TFPDependencies;
-begin
-  Result:=TFPDependencies.Create(TFPDependency);
-end;
 
 constructor TFPPackage.Create(ACollection: TCollection);
 begin
@@ -492,6 +482,7 @@ begin
   FInstalledVersion:=TFPVersion.Create;
   FOSes:=AllOSes;
   FCPUs:=AllCPUs;
+  FDependencies:=TFPDependencies.Create(TFPDependency);
 end;
 
 
@@ -503,8 +494,8 @@ begin
   inherited Destroy;
 end;
 
-procedure TFPPackage.SetName(const AValue: String);
 
+procedure TFPPackage.SetName(const AValue: String);
 begin
   If (AValue<>FName) and (AValue<>'') then
     If (Collection<>Nil) and (Collection is TFPPackages) then
@@ -515,17 +506,6 @@ begin
   FName:=AValue;
 end;
 
-function TFPPackage.GetDependencies: TFPDependencies;
-begin
-  If Not Assigned(FDependencies) then
-    FDependencies:=CreateDependencies;
-  Result:=FDependencies;
-end;
-
-function TFPPackage.GetHasDependencies: Boolean;
-begin
-  Result:=(Dependencies<>nil) and (FDependencies.Count>0);
-end;
 
 function TFPPackage.GetFileName: String;
 var
@@ -540,14 +520,13 @@ begin
     Result:=FFileName;
 end;
 
-procedure TFPPackage.LoadFromStream(Stream: TStream; Streamversion : Integer);
 
+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);
@@ -561,36 +540,32 @@ begin
   O:=[];
   For I:=1 to Count do
     begin
-    J:=GetEnumValue(TypeInfo(TOS),ReadString(Stream));
-    If (J<>-1) then
-      Include(O,TOS(J));
+      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));
+      J:=GetEnumValue(TypeInfo(TCPU),ReadString(Stream));
+      If (J<>-1) then
+        Include(C,TCPU(J));
     end;
   CPUS:=C;
-  FreeAndNil(FDependencies);
+  FDependencies.Clear;
   B:=ReadBoolean(Stream);
   If B then
-    begin
-    FDependencies:=CreateDependencies;
     FDependencies.LoadFromStream(Stream);
-    end
 end;
 
-procedure TFPPackage.SaveToStream(Stream: TStream);
 
+procedure TFPPackage.SaveToStream(Stream: TStream);
 Var
   Count : Integer;
   O : TOS;
   C : TCPU;
-
 begin
   WriteString(Stream,Version.AsString);
   WriteString(Stream,Name);
@@ -619,44 +594,42 @@ begin
   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
+  WriteBoolean(Stream,FDependencies.Count>0);
+  If FDependencies.Count>0 then
     FDependencies.SaveToStream(Stream);
 end;
 
-procedure TFPPackage.Assign(Source: TPersistent);
 
+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);
+      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.Assign(P.Installedversion);
+      Dependencies.Clear;
+      Dependencies.Assign(P.Dependencies);
     end
   else
     inherited Assign(Source);
 end;
 
-function TFPPackage.AddDependency(const APackageName: String;
-  AMinVersion: String): TFPDependency;
+
+function TFPPackage.AddDependency(const APackageName: String;AMinVersion: String): TFPDependency;
 begin
   Result:=Dependencies.AddDependency(APackageName,AMinVersion);
 end;
 
+
 { TFPPackages }
 
 function TFPPackages.GetPackage(Index : Integer): TFPPackage;
@@ -839,13 +812,12 @@ begin
 end;
 
 
+{$ifdef STATUSFILE}
 procedure TFPRepository.LoadStatusFromStream(Stream: TStream);
-
 Var
   L : TStrings;
   I : Integer;
   N,V : String;
-
 begin
   L:=TStringList.Create;
   Try
@@ -861,12 +833,11 @@ begin
   end;
 end;
 
-procedure TFPRepository.SaveStatusToStream(Stream: TStream);
 
+procedure TFPRepository.SaveStatusToStream(Stream: TStream);
 Var
   L : TStrings;
   I : Integer;
-
 begin
   L:=TStringList.Create;
   Try
@@ -880,11 +851,10 @@ begin
   end;
 end;
 
-procedure TFPRepository.LoadStatusFromFile(const AFileName: String);
 
+procedure TFPRepository.LoadStatusFromFile(const AFileName: String);
 Var
   F : TFileStream;
-
 begin
   F:=TFileStream.Create(AFileName,fmOpenRead);
   Try
@@ -894,11 +864,10 @@ begin
   end;
 end;
 
-procedure TFPRepository.SaveStatusToFile(const AFileName: String);
 
+procedure TFPRepository.SaveStatusToFile(const AFileName: String);
 Var
   F : TFileStream;
-
 begin
   If FileExists(AFileName) and BackupFiles then
     BackupFile(AFileName);
@@ -909,83 +878,87 @@ begin
     F.Free;
   end;
 end;
+{$endif STATUSFILE}
+
 
 function TFPRepository.IndexOfPackage(const APackageName: String): Integer;
 begin
   Result:=FPackages.IndexOfPackage(APackageName);
 end;
 
+
 function TFPRepository.FindPackage(const APackageName: String): TFPPackage;
 begin
   Result:=FPackages.FindPackage(APackageName);
 end;
 
+
 function TFPRepository.PackageByName(const APackageName: String): TFPPackage;
 begin
   Result:=FPackages.PackageByName(APackageName);
 end;
 
+
 procedure TFPRepository.RemovePackage(const APackageName: string);
 begin
   PackageByName(APackageName).Free;
 end;
 
+
 procedure TFPRepository.DeletePackage(Index : Integer);
 begin
   GetPackage(Index).Free;
 end;
 
-function TFPRepository.AddPackage(const APackageName: string): TFPPackage;
 
+function TFPRepository.AddPackage(const APackageName: string): TFPPackage;
 begin
   Result:=FPackages.AddPackage(APackageName);
 end;
 
-procedure TFPRepository.DoGetPackageDependencies(const APackageName: String;
-  List: TStringList; Level: Integer);
+
+procedure TFPRepository.DoGetPackageDependencies(const APackageName: 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,APackageName]);
   // Check if it is a known package.
   P:=FindPackage(APackageName);
-  If Assigned(P) and P.HasDependencies then
-    For I:=0 to P.Dependencies.Count-1 do
-      begin
+  If not Assigned(P) then
+    exit;
+  For I:=0 to P.Dependencies.Count-1 do
+    begin
       D1:=P.Dependencies[i];
       J:=List.IndexOf(APackageName);
       If J=-1 then
         begin
-        // Dependency not yet in list.
-        D2:=TFPDependency.Create(Nil);
-        D2.Assign(D1);
-        List.AddObject(D2.PackageName,D2);
+          // 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);
+          // 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;
 end;
 
-procedure TFPRepository.GetPackageDependencies(const APackageName: String;
-  List: TObjectList; Recurse: Boolean);
 
+procedure TFPRepository.GetPackageDependencies(const APackageName: String; List: TObjectList; Recurse: Boolean);
 Var
   L : TStringList;
   I : Integer;
-
 begin
   L:=TStringList.Create;
   Try
@@ -1007,6 +980,7 @@ begin
   FMinVersion.Assign(AValue);
 end;
 
+
 constructor TFPDependency.Create(ACollection: TCollection);
 begin
   inherited Create(ACollection);
@@ -1015,37 +989,45 @@ begin
   FCPUs:=AllCPUs;
 end;
 
+
 destructor TFPDependency.Destroy;
 begin
   FreeAndNil(FMinVersion);
   inherited Destroy;
 end;
 
-procedure TFPDependency.LoadFromStream(Stream: TStream; Streamversion: Integer
-  );
+
+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);
+var
+  S : TFPDependency;
 begin
   If Source is TFPDependency then
-    With Source as TFPDependency do
-      begin
-      Self.PackageName:=PackageName;
-      Self.MinVersion:=MinVersion;
-      end
+    begin
+      S:=Source as TFPDependency;
+      FPackageName:=S.PackageName;
+      FMinVersion.Assign(S.MinVersion);
+      FOSes:=S.OSes;
+      FCPUs:=S.CPUs;
+    end
   else
     inherited Assign(Source);
 end;
 
+
 { TFPDependencies }
 
 function TFPDependencies.GetDependency(Index : Integer): TFPDependency;
@@ -1053,12 +1035,13 @@ begin
   Result:=TFPDependency(Items[Index]);
 end;
 
-procedure TFPDependencies.SetDependency(Index : Integer;
-  const AValue: TFPDependency);
+
+procedure TFPDependencies.SetDependency(Index : Integer; const AValue: TFPDependency);
 begin
   Items[Index]:=AValue;
 end;
 
+
 function TFPDependencies.AddDependency(const APackageName: String; const AMinVersion: String): TFPDependency;
 begin
   Result:=Add as TFPDependency;
@@ -1067,6 +1050,7 @@ begin
     Result.MinVersion.AsString:=AMinVersion;
 end;
 
+
 { TFPMirror }
 
 constructor TFPMirror.Create(ACollection: TCollection);

+ 1 - 1
utils/fppkg/fpxmlrep.pp

@@ -327,7 +327,7 @@ begin
       OSesToXML(P.OSes,XML,Result);
     if P.CPUs<>AllCPUs then
       CPUsToXML(P.CPUs,XML,Result);
-    If P.HasDependencies then
+    If P.Dependencies.Count>0 then
       DependenciesToXML(P.Dependencies,XML,Result);
   Except
     Parent.RemoveChild(Result);

+ 52 - 12
utils/fppkg/pkgcommands.pp

@@ -208,8 +208,18 @@ function TCommandCompile.Execute(const Args:TActionArgs):boolean;
 begin
   if assigned(CurrentPackage) then
     begin
-      ExecuteAction(CurrentPackage,'installdependencies',Args);
-      ExecuteAction(CurrentPackage,'unzip',Args);
+      // For local files we need the information inside the zip to get the
+      // dependencies
+      if CurrentPackage.IsLocalPackage then
+        begin
+          ExecuteAction(CurrentPackage,'unzip',Args);
+          ExecuteAction(CurrentPackage,'installdependencies',Args);
+        end
+      else
+        begin
+          ExecuteAction(CurrentPackage,'installdependencies',Args);
+          ExecuteAction(CurrentPackage,'unzip',Args);
+        end;
     end;
   ExecuteAction(CurrentPackage,'fpmakecompile',Args);
   Result:=true;
@@ -220,8 +230,18 @@ function TCommandBuild.Execute(const Args:TActionArgs):boolean;
 begin
   if assigned(CurrentPackage) then
     begin
-      ExecuteAction(CurrentPackage,'installdependencies',Args);
-      ExecuteAction(CurrentPackage,'unzip',Args);
+      // For local files we need the information inside the zip to get the
+      // dependencies
+      if CurrentPackage.IsLocalPackage then
+        begin
+          ExecuteAction(CurrentPackage,'unzip',Args);
+          ExecuteAction(CurrentPackage,'installdependencies',Args);
+        end
+      else
+        begin
+          ExecuteAction(CurrentPackage,'installdependencies',Args);
+          ExecuteAction(CurrentPackage,'unzip',Args);
+        end;
     end;
   ExecuteAction(CurrentPackage,'fpmakebuild',Args);
   Result:=true;
@@ -257,14 +277,26 @@ end;
 function TCommandInstallDependencies.Execute(const Args:TActionArgs):boolean;
 var
   i : Integer;
+  MissingDependency,
   D : TFPDependency;
+  P,
   DepPackage : TFPPackage;
   L : TStringList;
   status : string;
 begin
   if not assigned(CurrentPackage) then
     Error(SErrNoPackageSpecified);
-  // List dependencies
+  // Load dependencies for local packages
+  if CurrentPackage.IsLocalPackage then
+    begin
+      ExecuteAction(CurrentPackage,'fpmakemanifest',Args);
+      P:=LoadPackageManifest(ManifestFileName);
+      // Update CurrentPackage
+      CurrentPackage.Assign(P);
+      CurrentPackage.IsLocalPackage:=true;
+    end;
+  // Find and List dependencies
+  MissingDependency:=nil;
   L:=TStringList.Create;
   for i:=0 to CurrentPackage.Dependencies.Count-1 do
     begin
@@ -278,23 +310,31 @@ begin
              (DepPackage.InstalledVersion.CompareVersion(D.MinVersion)<0) then
             begin
               if DepPackage.Version.CompareVersion(D.MinVersion)<0 then
-                status:='Not Available!'
+                begin
+                  status:='Not Available!';
+                  MissingDependency:=D;
+                end
               else
-                status:='Updating';
-              L.Add(DepPackage.Name);
+                begin
+                  status:='Updating';
+                  L.Add(DepPackage.Name);
+                end;
             end
           else
             status:='OK';
-          Log(vlDebug,SDbgPackageDependency,
+          Log(vlInfo,SLogPackageDependency,
               [D.PackageName,D.MinVersion.AsString,DepPackage.InstalledVersion.AsString,DepPackage.Version.AsString,status]);
-        end;
+        end
+      else
+        Log(vlDebug,SDbgPackageDependencyOtherTarget,[D.PackageName,MakeTargetString(CompilerOptions.CompilerCPU,CompilerOptions.CompilerOS)]);
     end;
+  // Give error on first missing dependency
+  if assigned(MissingDependency) then
+    Error(SErrNoPackageAvailable,[MissingDependency.PackageName,MissingDependency.MinVersion.AsString]);
   // Install needed updates
   for i:=0 to L.Count-1 do
     begin
       DepPackage:=CurrentRepository.PackageByName(L[i]);
-//      if DepPackage.Version.CompareVersion(D.MinVersion)<0 then
-//        Error(SErrNoPackageAvailable,[D.PackageName,D.MinVersion.AsString]);
       ExecuteAction(DepPackage,'install');
     end;
   FreeAndNil(L);

+ 3 - 2
utils/fppkg/pkgmessages.pp

@@ -72,14 +72,15 @@ Resourcestring
   SLogFPMKUnitDepTooOld      = 'Minimum version of %s is not installed, using internal fpmkunit with limited functionality';
   SLogSelectedMirror         = 'Selected mirror "%s"';
   SLogUpgradingConfig        = 'Configuration file "%s" is updated with new configuration settings';
-  SLogPackageMultipleLocations = 'Multiple installations found for package %s, using installation "%s"';
+  SLogPackageDependency      = 'Dependency on package %s %s, installed %s, available %s  (%s)';
 
   SDbgFound                  = 'Found';
   SDbgNotFound               = 'Not Found';
   SDbgDirectoryExists        = 'Directory "%s" %s';
   SDbgFileExists             = 'File "%s" %s';
   SDbgBackupFile             = 'Creating Backup File "%s"';
-  SDbgPackageDependency      = 'Dependency on package %s %s, installed %s, available %s  (%s)';
+  SDbgPackageMultipleLocations = 'Multiple installations found for package %s, using installation "%s"';
+  SDbgPackageDependencyOtherTarget  = 'Dependency on package %s is not for %s';
 
 implementation
 

+ 1 - 1
utils/fppkg/pkgmkconv.pp

@@ -502,7 +502,7 @@ begin
         Res:=R.IndexOfName(N)<>-1;
       GetOSCPU(V,OS,CPU);
       Pre[1]:=Upcase(Pre[1]);
-      Src.Add('    T:=P.Targets.Add'+Pre+'('''+Prefix+N+''');');
+      Src.Add('    T:=P.Targets.Add'+Pre+'('''+Prefix+N+'.pp'');');
       If (CPU<>'') then
         Src.Add('    T.CPU:=['+CPU+'];');
       If (OS<>'') then

+ 4 - 1
utils/fppkg/pkgoptions.pp

@@ -45,7 +45,8 @@ Type
     FFPMakeCompilerConfig : String;
     // Parameter options
     FCompilerConfig : String;
-    FInstallGlobal  : Boolean;
+    FInstallGlobal,
+    FRecoveryMode   : Boolean;
     function  GetOptString(Index: integer): String;
     procedure SetOptString(Index: integer; const AValue: String);
   Public
@@ -72,6 +73,7 @@ Type
     // Parameters
     Property CompilerConfig : String Read FCompilerConfig Write FCompilerConfig;
     Property InstallGlobal : Boolean Read FInstallGlobal Write FInstallGlobal;
+    Property RecoveryMode : Boolean Read FRecoveryMode Write FRecoveryMode;
   end;
 
 
@@ -258,6 +260,7 @@ begin
   // Parameter defaults
   FCompilerConfig:=FDefaultCompilerConfig;
   FInstallGlobal:=False;
+  FRecoveryMode:=False;
 end;
 
 

+ 64 - 51
utils/fppkg/pkgrepos.pp

@@ -12,6 +12,8 @@ function GetRemoteRepositoryURL(const AFileName:string):string;
 
 procedure LoadLocalMirrors;
 procedure LoadLocalRepository;
+function  LoadOrCreatePackage(const AName:string):TFPPackage;
+function  LoadPackageManifest(const AManifestFN:string):TFPPackage;
 procedure FindInstalledPackages(ACompilerOptions:TCompilerOptions;showdups:boolean=true);
 procedure CheckFPMakeDependencies;
 procedure ListLocalRepository(all:boolean=false);
@@ -189,17 +191,60 @@ begin
 end;
 
 
-procedure FindInstalledPackages(ACompilerOptions:TCompilerOptions;showdups:boolean=true);
+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 LoadOrCreatePackage(const AName:string):TFPPackage;
-  begin
-    result:=CurrentRepository.FindPackage(AName);
-    if not assigned(result) then
+
+function LoadPackageManifest(const AManifestFN:string):TFPPackage;
+var
+  X : TFPXMLRepositoryHandler;
+  i : integer;
+  DoAdd : Boolean;
+  NewP : TFPPackage;
+  NewPackages : TFPPackages;
+begin
+  result:=nil;
+  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
-        result:=CurrentRepository.AddPackage(AName);
-        result.IsLocalPackage:=true;
+        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);
+        // Copy contents
+        if DoAdd then
+          result.Assign(NewP);
       end;
+  finally
+    X.Free;
+    NewPackages.Free;
   end;
+end;
+
+
+procedure FindInstalledPackages(ACompilerOptions:TCompilerOptions;showdups:boolean=true);
 
   procedure LoadUnitConfigFromFile(APackage:TFPPackage;const AFileName: String);
   Var
@@ -217,7 +262,7 @@ procedure FindInstalledPackages(ACompilerOptions:TCompilerOptions;showdups:boole
       if not APackage.InstalledVersion.Empty then
         begin
           if showdups then
-            Log(vlInfo,SLogPackageMultipleLocations,[APackage.Name,ExtractFilePath(AFileName)]);
+            Log(vlDebug,SDbgPackageMultipleLocations,[APackage.Name,ExtractFilePath(AFileName)]);
         end;
     Finally
       L.Free;
@@ -292,10 +337,16 @@ var
   P : TFPPackage;
   ReqVer : TFPVersion;
 begin
+  // Reset availability
+  for i:=1 to FPMKUnitDepCount do
+    FPMKUnitDepAvailable[i]:=false;
+  // Not version check needed in Recovery mode, we always need to use
+  // the internal bootstrap procedure
+  if GlobalOptions.RecoveryMode then
+    exit;
   // Check for fpmkunit dependencies
   for i:=1 to FPMKUnitDepCount do
     begin
-      FPMKUnitDepAvailable[i]:=false;
       P:=CurrentRepository.FindPackage(FPMKUnitDeps[i].package);
       if P<>nil then
         begin
@@ -350,47 +401,6 @@ end;
 
 procedure RebuildRemoteRepository;
 
-  procedure AddPackage(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);
-      DeleteFile(ManifestFileName);
-      // Update or Add packages to repository
-      for i:=0 to NewPackages.Count-1 do
-        begin
-          NewP:=NewPackages[i];
-          DoAdd:=True;
-          P:=CurrentRepository.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:=CurrentRepository.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;
@@ -422,7 +432,10 @@ begin
           end;
         { Load manifest.xml }
         if FileExists(ManifestFileName) then
-          AddPackage(ManifestFileName)
+          begin
+            LoadPackageManifest(ManifestFileName);
+            DeleteFile(ManifestFileName);
+          end
         else
           Writeln('No manifest found in archive ',ArchiveSL[i]);
 

Niektoré súbory nie sú zobrazené, pretože je v týchto rozdielových dátach zmenené mnoho súborov