ソースを参照

Merge EDSP 0.5 w/ multi-arch support for external solvers

"I am going to merge it tomorrow…"
David Kalnischkies 12 年 前
コミット
59df9e241d
共有2 個のファイルを変更した54 個の追加10 個の削除を含む
  1. 30 3
      apt-pkg/edsp.cc
  2. 24 7
      doc/external-dependency-solver-protocol.txt

+ 30 - 3
apt-pkg/edsp.cc

@@ -18,6 +18,7 @@
 #include <apt-pkg/pkgcache.h>
 #include <apt-pkg/pkgcache.h>
 #include <apt-pkg/cacheiterators.h>
 #include <apt-pkg/cacheiterators.h>
 #include <apt-pkg/strutl.h>
 #include <apt-pkg/strutl.h>
+#include <apt-pkg/pkgrecords.h>
 
 
 #include <ctype.h>
 #include <ctype.h>
 #include <stddef.h>
 #include <stddef.h>
@@ -87,7 +88,12 @@ bool EDSP::WriteLimitedScenario(pkgDepCache &Cache, FILE* output,
 void EDSP::WriteScenarioVersion(pkgDepCache &Cache, FILE* output, pkgCache::PkgIterator const &Pkg,
 void EDSP::WriteScenarioVersion(pkgDepCache &Cache, FILE* output, pkgCache::PkgIterator const &Pkg,
 				pkgCache::VerIterator const &Ver)
 				pkgCache::VerIterator const &Ver)
 {
 {
+   pkgRecords Recs(Cache);
+   pkgRecords::Parser &rec = Recs.Lookup(Ver.FileList());
+   string srcpkg = rec.SourcePkg().empty() ? Pkg.Name() : rec.SourcePkg();
+
    fprintf(output, "Package: %s\n", Pkg.Name());
    fprintf(output, "Package: %s\n", Pkg.Name());
+   fprintf(output, "Source: %s\n", srcpkg.c_str());
    fprintf(output, "Architecture: %s\n", Ver.Arch());
    fprintf(output, "Architecture: %s\n", Ver.Arch());
    fprintf(output, "Version: %s\n", Ver.VerStr());
    fprintf(output, "Version: %s\n", Ver.VerStr());
    if (Pkg.CurrentVer() == Ver)
    if (Pkg.CurrentVer() == Ver)
@@ -107,10 +113,22 @@ void EDSP::WriteScenarioVersion(pkgDepCache &Cache, FILE* output, pkgCache::PkgI
    else if ((Ver->MultiArch & pkgCache::Version::Same) == pkgCache::Version::Same)
    else if ((Ver->MultiArch & pkgCache::Version::Same) == pkgCache::Version::Same)
       fprintf(output, "Multi-Arch: same\n");
       fprintf(output, "Multi-Arch: same\n");
    signed short Pin = std::numeric_limits<signed short>::min();
    signed short Pin = std::numeric_limits<signed short>::min();
-   for (pkgCache::VerFileIterator File = Ver.FileList(); File.end() == false; ++File) {
-      signed short const p = Cache.GetPolicy().GetPriority(File.File());
+   std::set<string> Releases;
+   for (pkgCache::VerFileIterator I = Ver.FileList(); I.end() == false; ++I) {
+      pkgCache::PkgFileIterator File = I.File();
+      signed short const p = Cache.GetPolicy().GetPriority(File);
       if (Pin < p)
       if (Pin < p)
 	 Pin = p;
 	 Pin = p;
+      if ((File->Flags & pkgCache::Flag::NotSource) != pkgCache::Flag::NotSource) {
+	 string Release = File.RelStr();
+	 if (!Release.empty())
+	    Releases.insert(Release);
+      }
+   }
+   if (!Releases.empty()) {
+       fprintf(output, "APT-Release:\n");
+       for (std::set<string>::iterator R = Releases.begin(); R != Releases.end(); ++R)
+	   fprintf(output, " %s\n", R->c_str());
    }
    }
    fprintf(output, "APT-Pin: %d\n", Pin);
    fprintf(output, "APT-Pin: %d\n", Pin);
    if (Cache.GetCandidateVer(Pkg) == Ver)
    if (Cache.GetCandidateVer(Pkg) == Ver)
@@ -231,7 +249,16 @@ bool EDSP::WriteRequest(pkgDepCache &Cache, FILE* output, bool const Upgrade,
 	 continue;
 	 continue;
       req->append(" ").append(Pkg.FullName());
       req->append(" ").append(Pkg.FullName());
    }
    }
-   fprintf(output, "Request: EDSP 0.4\n");
+   fprintf(output, "Request: EDSP 0.5\n");
+
+   const char *arch = _config->Find("APT::Architecture").c_str();
+   std::vector<string> archs = APT::Configuration::getArchitectures();
+   fprintf(output, "Architecture: %s\n", arch);
+   fprintf(output, "Architectures:");
+   for (std::vector<string>::const_iterator a = archs.begin(); a != archs.end(); ++a)
+       fprintf(output, " %s", a->c_str());
+   fprintf(output, "\n");
+
    if (del.empty() == false)
    if (del.empty() == false)
       fprintf(output, "Remove: %s\n", del.c_str()+1);
       fprintf(output, "Remove: %s\n", del.c_str()+1);
    if (inst.empty() == false)
    if (inst.empty() == false)

+ 24 - 7
doc/external-dependency-solver-protocol.txt

@@ -1,4 +1,4 @@
-# APT External Dependency Solver Protocol (EDSP) - version 0.4
+# APT External Dependency Solver Protocol (EDSP) - version 0.5
 
 
 This document describes the communication protocol between APT and
 This document describes the communication protocol between APT and
 external dependency solvers. The protocol is called APT EDSP, for "APT
 external dependency solvers. The protocol is called APT EDSP, for "APT
@@ -110,16 +110,24 @@ Within a dependency solving scenario, a request represents the action on
 installed packages requested by the user.
 installed packages requested by the user.
 
 
 A request is a single Deb 822 stanza opened by a mandatory Request field
 A request is a single Deb 822 stanza opened by a mandatory Request field
-and followed by a mixture of action and preference fields.
+and followed by a mixture of action, preference, and global
+configuration fields.
 
 
 The value of the **Request:** field is a string describing the EDSP
 The value of the **Request:** field is a string describing the EDSP
 protocol which will be used to communicate. At present, the string must
 protocol which will be used to communicate. At present, the string must
-be `EDSP 0.4`.
+be `EDSP 0.5`. Request fields are mainly used to identify the beginning
+of a request stanza; their actual values are otherwise not used by the
+EDSP protocol.
 
 
-a unique request identifier, such as an
-UUID. Request fields are mainly used to identify the beginning of a
-request stanza; their actual values are otherwise not used by the EDSP
-protocol.
+The following **configuration fields** are supported in request stanzas:
+
+- **Architecture:** (mandatory) The name of the *native* architecture on
+  the user machine (see also: `dpkg --print-architecture`)
+
+- **Architectures:** (optional, defaults to the native architecture) A
+  space separated list of *all* architectures known to APT (this is
+  roughly equivalent to the union of `dpkg --print-architecture` and
+  `dpkg --print-foreign-architectures`)
 
 
 The following **action fields** are supported in request stanzas:
 The following **action fields** are supported in request stanzas:
 
 
@@ -201,6 +209,15 @@ field. The following fields are supported in package stanzas:
   should be removed by the solver only when the Autoremove action is
   should be removed by the solver only when the Autoremove action is
   requested (see Request section).
   requested (see Request section).
 
 
+- **APT-Release:** (optional) The releases the package belongs to, according to
+  APT. The format of this field is multiline with one value per line and the
+  first line (the one containing the field name) empty. Each subsequent line
+  corresponds to one of the releases the package belongs to and looks like
+  this: `o=Debian,a=unstable,n=sid,l=Debian,c=main`. That is, each release line
+  is a comma-separated list of "key=value" pairs, each of which denotes a
+  Release file entry (Origin, Label, Codename, etc.) in the format of
+  APT_PREFERENCES(5).
+
 ### Answer
 ### Answer
 
 
 An answer from the external solver to APT is either a *solution* or an
 An answer from the external solver to APT is either a *solution* or an