瀏覽代碼

* Moved all logic to determine in which repository to install a package into
one method.
* Re-designed the logic to determine where to install packages. Documented
the logic in repositorylogics.dia.
* Partly implemented this new logic.
* Added tests.

git-svn-id: trunk@36300 -

joost 8 年之前
父節點
當前提交
408cae639f

+ 1 - 0
.gitattributes

@@ -3417,6 +3417,7 @@ packages/fppkg/Makefile svneol=native#text/plain
 packages/fppkg/Makefile.fpc svneol=native#text/plain
 packages/fppkg/Makefile.fpc.fpcmake svneol=native#text/plain
 packages/fppkg/fpmake.pp svneol=native#text/plain
+packages/fppkg/repositorylogics.dia -text svneol=unset#application/x-gzip
 packages/fppkg/src/fpmkunitsrc.inc svneol=native#text/plain
 packages/fppkg/src/fprepos.pp svneol=native#text/plain
 packages/fppkg/src/fpxmlrep.pp svneol=native#text/plain

二進制
packages/fppkg/repositorylogics.dia


+ 1 - 1
packages/fppkg/src/pkgfpmake.pp

@@ -442,7 +442,7 @@ begin
   // manifest command does not use the --prefix and --baseinstalldir parameters.
   if (command<>'manifest') then
     begin
-      InstallRepo := PackageManager.RepositoryByName(PackageManager.Options.CommandLineSection.InstallRepository);
+      InstallRepo := PackageManager.GetInstallRepository(P);
 
       if not Assigned(InstallRepo.DefaultPackagesStructure) then
         begin

+ 44 - 19
packages/fppkg/src/pkgfppkg.pp

@@ -61,7 +61,7 @@ type
     function FindRepository(ARepositoryName: string): TFPRepository;
     function RepositoryByName(ARepositoryName: string): TFPRepository;
 
-    function GetInstallRepository(APackage: TFPPackage): TFPRepository;
+    function GetInstallRepository(ASourcePackage: TFPPackage): TFPRepository;
     function PackageLocalArchive(APackage:TFPPackage): String;
     function PackageBuildPath(APackage:TFPPackage):String;
 
@@ -191,14 +191,6 @@ begin
       FOptions.LoadFromFile(cfgfile);
     end;
   FOptions.CommandLineSection.CompilerConfig:=FOptions.GlobalSection.CompilerConfig;
-  if FOptions.GlobalSection.InstallRepository <> '' then
-    FOptions.CommandLineSection.InstallRepository:=FOptions.GlobalSection.InstallRepository
-  else
-    begin
-      FirstRepoConf :=  FOptions.GetSectionByName('Repository');
-      if Assigned(FirstRepoConf) then
-        FOptions.CommandLineSection.InstallRepository := (FirstRepoConf as TFppkgRepositoryOptionSection).RepositoryName;
-    end;
   // Tracing of what we've done above, need to be done after the verbosity is set
   if GeneratedConfig then
     pkgglobals.Log(llDebug,SLogGeneratingGlobalConfig,[cfgfile])
@@ -559,22 +551,55 @@ begin
     Raise EPackage.CreateFmt(SErrMissingInstallRepo,[ARepositoryName]);
 end;
 
-function TpkgFPpkg.GetInstallRepository(APackage: TFPPackage): TFPRepository;
+function TpkgFPpkg.GetInstallRepository(ASourcePackage: TFPPackage): TFPRepository;
 var
-  InstRepositoryName: string;
-  Repo: TFPRepository;
+  SourceRepository: TFPRepository;
+  RepoName: string;
+  i: Integer;
 begin
-  Result := RepositoryByName(Options.CommandLineSection.InstallRepository);
-  if Assigned(APackage) and Assigned(APackage.Repository) and Assigned(APackage.Repository.DefaultPackagesStructure) then
+  // Determine the repository to install a package into. See the
+  // repositorylogics.dia file.
+  pkgglobals.Log(llDebug, SLogDetermineInstallRepo, [ASourcePackage.GetDebugName]);
+  RepoName := Options.CommandLineSection.InstallRepository;
+  if RepoName <> '' then
+    // If an install-repository is given on the command line, this overrides
+    // everything.
+    pkgglobals.Log(llDebug, SLogUseCommandLineRepo, [RepoName])
+  else
     begin
-      InstRepositoryName := APackage.Repository.DefaultPackagesStructure.InstallRepositoryName;
-      if (InstRepositoryName<>'') then
+      // The source-repository is already determined by the source-package, which
+      // is a member of the source-repository.
+      SourceRepository := ASourcePackage.Repository;
+      Assert(Assigned(SourceRepository));
+      Assert(SourceRepository.RepositoryType = fprtAvailable);
+
+      // For now, skip the check for original sources of already installed packages.
+
+      Assert(Assigned(SourceRepository.DefaultPackagesStructure));
+      RepoName := SourceRepository.DefaultPackagesStructure.InstallRepositoryName;
+      if RepoName<>'' then
+        pkgglobals.Log(llDebug, SLogUseSourceRepoInstRepo, [RepoName, SourceRepository.RepositoryName])
+      else
         begin
-          Repo := FindRepository(InstRepositoryName);
-          if Assigned(Repo) then
-            Result := Repo;
+          RepoName := Options.GlobalSection.InstallRepository;
+          if RepoName<>'' then
+            pkgglobals.Log(llDebug, SLogUseConfigurationRepo, [RepoName])
+          else
+            begin
+              for i := RepositoryList.Count-1 downto 0 do
+                begin
+                  if (RepositoryList[i] as TFPRepository).RepositoryType = fprtInstalled then
+                    begin
+                      Result := TFPRepository(RepositoryList[i]);
+                      pkgglobals.Log(llDebug, SLogUseLastRepo, [Result.RepositoryName]);
+                      Exit;
+                    end;
+                end;
+              raise EPackage.Create(SErrNoInstallRepoAvailable);
+            end;
         end;
     end;
+  Result := RepositoryByName(RepoName);
 end;
 
 function TpkgFPpkg.PackageLocalArchive(APackage: TFPPackage): String;

+ 6 - 0
packages/fppkg/src/pkgmessages.pp

@@ -62,6 +62,7 @@ Resourcestring
   SErrCannotModifyRepository = 'The repository of an TFPPackages-instance can not be changed.';
   SErrRepositoryNotAssigned  = 'Repository not assigned';
   SErrInstallationImpossible = 'It is not possible to install the package "%s" in repository "%s".';
+  SErrNoInstallRepoAvailable = 'There are no repositories configured to install packages into';
 
   SLogGeneratingFPMake       = 'Generating fpmake.pp';
   SLogNotCompilingFPMake     = 'Skipping compiling of fpmake.pp, fpmake executable already exists';
@@ -100,6 +101,11 @@ Resourcestring
   SLogCheckBrokenDependenvies= 'Checking for broken dependencies';
   SLogFailedToCreateManifest = 'Failed to create manifest from fpmake.pp-file (%s) while scanning for available packages: %s';
   SLogUseInternalFpmkunit    = 'Fpmkunit not available, fallback to internal version.';
+  SLogDetermineInstallRepo   = 'Determine in which repository package "%s" has to be installed';
+  SLogUseCommandLineRepo     = 'Use repository "%s" provided on the command-line';
+  SLogUseSourceRepoInstRepo  = 'Use the installation repository "%s" which is coupled to the source repository "%s"';
+  SLogUseConfigurationRepo   = 'Use repository "%s" provided in the configuration files';
+  SLogUseLastRepo            = 'Use the last repository "%s"';
 
   SLogCfgHeader                      = 'Settings from configuration-files:';
   SLogCfgSectionHeader               = ' %s-section:';

+ 107 - 0
packages/fppkg/tests/fullfpcinstallationtests.pas

@@ -8,6 +8,7 @@ uses
   Classes,
   SysUtils,
   fpcunit,
+  IniFiles,
   testdecorator,
   testregistry,
   CustApp,
@@ -39,6 +40,9 @@ type
     procedure TestFPMakeCommandLikePackageVariants;
     procedure TestFpmakePluginDependencies;
     procedure TestCleanupOfTemporaryBuildpath;
+    procedure TestDefaultInstallLocation;
+    procedure TestSourceRepositoryInstallLocation;
+    procedure TestConfiguredInstallLocation;
   end;
 
   { TFullFPCInstallationSetup }
@@ -354,6 +358,109 @@ begin
     end;
 end;
 
+procedure TFullFPCInstallationTests.TestDefaultInstallLocation;
+var
+  FPPKGFilename: String;
+  ConfigFile: TIniFile;
+begin
+  TFullFPCInstallationSetup.SyncPackageIntoCurrentTest('packagea');
+  TFullFPCInstallationSetup.SyncPackageIntoCurrentTest('packageb');
+
+  // Remove the installrepository setting from fppkg.cfg
+  FPPKGFilename := ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestPath, 'etc', 'fppkg.cfg']);
+  ConfigFile := TIniFile.Create(FPPKGFilename);
+  try
+    ConfigFile.DeleteKey('Defaults', 'InstallRepository');
+    ConfigFile.UpdateFile;
+  finally
+    ConfigFile.Free;
+  end;
+
+  // Should install into user
+  RunFppkgIndir(TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath + 'packagea', ['install'], 'Install package A');
+
+  Check(FileExists(ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestPath, 'user', 'lib', 'fpc', TFullFPCInstallationSetup.GetCompilerVersion, 'units',TFullFPCInstallationSetup.GetTargetString,'packagea','PackageAUnitA.ppu'])), 'PackageAUnitA.ppu not found');
+  Check(FileExists(ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestPath, 'user', 'lib', 'fpc', TFullFPCInstallationSetup.GetCompilerVersion, 'units',TFullFPCInstallationSetup.GetTargetString,'packagea','PackageAUnitA.o'])), 'PackageAUnitA.o not found');
+  Check(FileExists(ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestPath, 'user', 'lib', 'fpc', TFullFPCInstallationSetup.GetCompilerVersion, 'fpmkinst',TFullFPCInstallationSetup.GetTargetString,'packagea.fpm'])), 'packagea.fpm not found');
+
+  // Command-line should override default, so install in fpc
+  RunFppkgIndir(TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath + 'packageb', ['install', '-i', 'fpc'], 'Install package B');
+
+  Check(FileExists(ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestPath, 'lib', 'fpc', TFullFPCInstallationSetup.GetCompilerVersion, 'units',TFullFPCInstallationSetup.GetTargetString,'PackageB','PackageBUnitB.ppu'])), 'PackageBUnitB.ppu not found');
+  Check(FileExists(ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestPath, 'lib', 'fpc', TFullFPCInstallationSetup.GetCompilerVersion, 'units',TFullFPCInstallationSetup.GetTargetString,'PackageB','PackageBUnitB.o'])), 'PackageBUnitB.o not found');
+  Check(FileExists(ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestPath, 'lib', 'fpc', TFullFPCInstallationSetup.GetCompilerVersion, 'fpmkinst',TFullFPCInstallationSetup.GetTargetString,'PackageB.fpm'])), 'PackageB.fpm not found');
+end;
+
+procedure TFullFPCInstallationTests.TestSourceRepositoryInstallLocation;
+var
+  LocalPackagesRepoCfgFilename: String;
+  ConfigFile: TIniFile;
+begin
+  TFullFPCInstallationSetup.SyncPackageIntoCurrentTest('packagea');
+  TFullFPCInstallationSetup.SyncPackageIntoCurrentTest('packageb');
+
+  // Remove the installrepository setting from fppkg.cfg
+  LocalPackagesRepoCfgFilename := ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestPath, 'user', 'config', 'conf.d', 'lazaruspackagesrepo.conf']);
+  ConfigFile := TIniFile.Create(LocalPackagesRepoCfgFilename);
+  try
+    ConfigFile.WriteString('UninstalledSourceRepository', 'Name', 'localpackages');
+    ConfigFile.WriteString('UninstalledSourceRepository', 'Description', 'Local packages');
+    ConfigFile.WriteString('UninstalledSourceRepository', 'Path', ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestPath, 'packages']));
+    ConfigFile.WriteString('UninstalledSourceRepository', 'InstallRepository', 'fpc');
+    ConfigFile.UpdateFile;
+  finally
+    ConfigFile.Free;
+  end;
+
+  // Should install into fpc, as it is installed from the localpackages repository
+  // which has fpc as install-repository
+  RunFppkgIndir(TFullFPCInstallationSetup.GetCurrentTestPath, ['install', 'packagea'], 'Install package A from source repository');
+
+  Check(FileExists(ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestPath, 'lib', 'fpc', TFullFPCInstallationSetup.GetCompilerVersion, 'units',TFullFPCInstallationSetup.GetTargetString,'packagea','PackageAUnitA.ppu'])), 'PackageAUnitA.ppu not found');
+  Check(FileExists(ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestPath, 'lib', 'fpc', TFullFPCInstallationSetup.GetCompilerVersion, 'units',TFullFPCInstallationSetup.GetTargetString,'packagea','PackageAUnitA.o'])), 'PackageAUnitA.o not found');
+  Check(FileExists(ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestPath, 'lib', 'fpc', TFullFPCInstallationSetup.GetCompilerVersion, 'fpmkinst',TFullFPCInstallationSetup.GetTargetString,'packagea.fpm'])), 'packagea.fpm not found');
+
+  // Command-line should override default, so install in user
+  RunFppkgIndir(TFullFPCInstallationSetup.GetCurrentTestPath, ['install', '-i', 'user', 'packageb'], 'Install package B from user repository');
+
+  Check(FileExists(ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestPath, 'user', 'lib', 'fpc', TFullFPCInstallationSetup.GetCompilerVersion, 'units',TFullFPCInstallationSetup.GetTargetString,'PackageB','PackageBUnitB.ppu'])), 'PackageBUnitB.ppu not found');
+  Check(FileExists(ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestPath, 'user', 'lib', 'fpc', TFullFPCInstallationSetup.GetCompilerVersion, 'units',TFullFPCInstallationSetup.GetTargetString,'PackageB','PackageBUnitB.o'])), 'PackageBUnitB.o not found');
+  Check(FileExists(ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestPath, 'user', 'lib', 'fpc', TFullFPCInstallationSetup.GetCompilerVersion, 'fpmkinst',TFullFPCInstallationSetup.GetTargetString,'PackageB.fpm'])), 'PackageB.fpm not found');
+end;
+
+procedure TFullFPCInstallationTests.TestConfiguredInstallLocation;
+var
+  FPPKGFilename: String;
+  ConfigFile: TIniFile;
+begin
+  TFullFPCInstallationSetup.SyncPackageIntoCurrentTest('packagea');
+  TFullFPCInstallationSetup.SyncPackageIntoCurrentTest('packageb');
+
+  // Remove the installrepository setting from fppkg.cfg
+  FPPKGFilename := ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestPath, 'etc', 'fppkg.cfg']);
+  ConfigFile := TIniFile.Create(FPPKGFilename);
+  try
+    ConfigFile.WriteString('Defaults', 'InstallRepository', 'fpc');
+    ConfigFile.UpdateFile;
+  finally
+    ConfigFile.Free;
+  end;
+
+  // Should install into fpc
+  RunFppkgIndir(TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath + 'packagea', ['install'], 'Install package A');
+
+  Check(FileExists(ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestPath, 'lib', 'fpc', TFullFPCInstallationSetup.GetCompilerVersion, 'units',TFullFPCInstallationSetup.GetTargetString,'packagea','PackageAUnitA.ppu'])), 'PackageAUnitA.ppu not found');
+  Check(FileExists(ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestPath, 'lib', 'fpc', TFullFPCInstallationSetup.GetCompilerVersion, 'units',TFullFPCInstallationSetup.GetTargetString,'packagea','PackageAUnitA.o'])), 'PackageAUnitA.o not found');
+  Check(FileExists(ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestPath, 'lib', 'fpc', TFullFPCInstallationSetup.GetCompilerVersion, 'fpmkinst',TFullFPCInstallationSetup.GetTargetString,'packagea.fpm'])), 'packagea.fpm not found');
+
+  // Command-line should override default, so install in user
+  RunFppkgIndir(TFullFPCInstallationSetup.GetCurrentTestBasePackagesPath + 'packageb', ['install', '-i', 'user'], 'Install package B');
+
+  Check(FileExists(ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestPath, 'user', 'lib', 'fpc', TFullFPCInstallationSetup.GetCompilerVersion, 'units',TFullFPCInstallationSetup.GetTargetString,'PackageB','PackageBUnitB.ppu'])), 'PackageBUnitB.ppu not found');
+  Check(FileExists(ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestPath, 'user', 'lib', 'fpc', TFullFPCInstallationSetup.GetCompilerVersion, 'units',TFullFPCInstallationSetup.GetTargetString,'PackageB','PackageBUnitB.o'])), 'PackageBUnitB.o not found');
+  Check(FileExists(ConcatPaths([TFullFPCInstallationSetup.GetCurrentTestPath, 'user', 'lib', 'fpc', TFullFPCInstallationSetup.GetCompilerVersion, 'fpmkinst',TFullFPCInstallationSetup.GetTargetString,'PackageB.fpm'])), 'PackageB.fpm not found');
+end;
+
 procedure TFullFPCInstallationTests.TestListPackages;
 var
   s: String;