[Aptitude-svn-commit] r3676 - in branches/aptitude-0.3/aptitude: . doc/en src/cmdline src/generic

Daniel Burrows dburrows at costa.debian.org
Mon Jul 25 23:23:11 UTC 2005


Author: dburrows
Date: Mon Jul 25 23:23:08 2005
New Revision: 3676

Modified:
   branches/aptitude-0.3/aptitude/ChangeLog
   branches/aptitude-0.3/aptitude/doc/en/manpage.xml
   branches/aptitude-0.3/aptitude/src/cmdline/cmdline_changelog.cc
   branches/aptitude-0.3/aptitude/src/generic/pkg_changelog.cc
   branches/aptitude-0.3/aptitude/src/generic/pkg_changelog.h
Log:
Allow source packages to be passed to 'aptitude changelog'.

Modified: branches/aptitude-0.3/aptitude/ChangeLog
==============================================================================
--- branches/aptitude-0.3/aptitude/ChangeLog	(original)
+++ branches/aptitude-0.3/aptitude/ChangeLog	Mon Jul 25 23:23:08 2005
@@ -1,6 +1,11 @@
 2005-07-25  Daniel Burrows  <dburrows at debian.org>
 
-	* src/generic/cmdling_changelog.cc, src/generic/pkg_changelog.cc, src/generic/pkg_changelog.h:
+	* doc/en/manpage.xml, src/cmdline/cmdline_changelog.cc, src/generic/pkg_changelog.cc, src/generic/pkg_changelog.h:
+
+	  Let the user pass source packages as well as binary packages
+	  into the "changelog" command-line action.
+
+	* src/cmdline/cmdline_changelog.cc, src/generic/pkg_changelog.cc, src/generic/pkg_changelog.h:
 
 	  Add the ability to find changelog based on the source package
 	  name as well as an iterator to a binary package version.  Also

Modified: branches/aptitude-0.3/aptitude/doc/en/manpage.xml
==============================================================================
--- branches/aptitude-0.3/aptitude/doc/en/manpage.xml	(original)
+++ branches/aptitude-0.3/aptitude/doc/en/manpage.xml	Mon Jul 25 23:23:08 2005
@@ -542,7 +542,7 @@
 	<listitem>
 	  <para>
 	    Downloads and displays the Debian changelog for each of
-	    the given packages.
+	    the given source or binary packages.
 	  </para>
 
 	  <para>

Modified: branches/aptitude-0.3/aptitude/src/cmdline/cmdline_changelog.cc
==============================================================================
--- branches/aptitude-0.3/aptitude/src/cmdline/cmdline_changelog.cc	(original)
+++ branches/aptitude-0.3/aptitude/src/cmdline/cmdline_changelog.cc	Mon Jul 25 23:23:08 2005
@@ -15,10 +15,127 @@
 #include <generic/pkg_changelog.h>
 
 #include <apt-pkg/error.h>
+#include <apt-pkg/metaindex.h>
 #include <apt-pkg/progress.h>
+#include <apt-pkg/sourcelist.h>
+#include <apt-pkg/srcrecords.h>
 
 using namespace std;
 
+/** Represents the information needed to retrieve a changelog. */
+struct changelog_entity
+{
+  /** The name of the source package. */
+  std::string pkg;
+
+  /** The name of the source version. */
+  std::string ver;
+
+  /** The section of the package. */
+  std::string section;
+
+  /** Initializes the empty entity: all the members are 0-length
+   *  strings.
+   */
+  changelog_entity():pkg(), ver(), section()
+  {
+  }
+
+  changelog_entity(const std::string &_pkg,
+		   const std::string &_ver,
+		   const std::string &_section)
+    :pkg(_pkg), ver(_ver), section(_section)
+  {
+  }
+
+  changelog_entity &operator=(const changelog_entity &other)
+  {
+    pkg = other.pkg;
+    ver = other.ver;
+    section = other.section;
+  }
+};
+
+/** Find a source record in the given set of source records
+ *  corresponding to the package pkg, version ver.
+ *
+ *  \param records the source records object
+ *  \param pkg the package name to match on
+ *  \param ver the version string to match on
+ *
+ *  \return a matching changelog entity, or the empty entity if no
+ *  such entity exists.
+ */
+changelog_entity find_src_ver(pkgSourceList &list,
+			      const std::string &pkg,
+			      const std::string &ver)
+{
+  pkgSrcRecords records(list);
+  records.Restart();
+
+  pkgSrcRecords :: Parser *parser = records.Find(pkg.c_str());
+
+  while(parser != NULL && parser->Version() != ver)
+    parser = records.Find(pkg.c_str());
+
+  if(parser == NULL)
+    return changelog_entity();
+  else
+    return changelog_entity(pkg, ver, parser->Section());
+}
+
+/** Find a source record in the given set of source records
+ *  corresponding to the given package and archive.  Expects no
+ *  pending errors when it starts.
+ *
+ *  \param records the source records object
+ *  \param pkg the package name to match on
+ *  \param ver the version string to match on
+ *
+ *  \return a matching changelog entity, or the empty entity
+ *  ("","","") if no such entity exists.
+ */
+
+// Based heavily on pkgSrcRecords.
+changelog_entity find_src_archive(pkgSourceList &list,
+				  const std::string &pkg,
+				  const std::string &archive)
+{
+  for(pkgSourceList::const_iterator i = list.begin(); i!=list.end(); ++i)
+    {
+      if((*i)->GetDist() != archive)
+	continue;
+
+      vector<pkgIndexFile *> *indexes = (*i)->GetIndexFiles();
+
+      for(vector<pkgIndexFile *> :: const_iterator j = indexes->begin();
+	  j != indexes->end(); ++j)
+	{
+	  auto_ptr<pkgSrcRecords :: Parser> p((*j)->CreateSrcParser());
+
+	  if(_error->PendingError())
+	    return changelog_entity();
+	  if(p.get() != 0)
+	    {
+	      // Step through the file until we reach the end or find
+	      // the package:
+	      while(p.get()->Step() == true)
+		{
+		  if(_error->PendingError() == true)
+		    return changelog_entity();
+
+		  if(p.get()->Package() == pkg)
+		    return changelog_entity(pkg,
+					    p.get()->Version(),
+					    p.get()->Section());
+		}
+	    }
+	}
+    }
+
+  return changelog_entity();
+}
+
 bool do_cmdline_changelog(const vector<string> &packages)
 {
   const char *pager="/usr/bin/sensible-pager";
@@ -45,46 +162,91 @@
 
       pkgCache::PkgIterator pkg=(*apt_cache_file)->FindPkg(package);
 
-      if(pkg.end())
-	{
-	  _error->Error("Can't find package %s", package.c_str());
-	  continue;
-	}
-
-      pkgCache::VerIterator ver=cmdline_find_ver(pkg,
-						 source, sourcestr);
+      pkg_changelog *cl=NULL;
 
-      if(!ver.end())
+      // For real packages/versions, we can do a sanity check.
+      if(!pkg.end())
 	{
-	  // Move this to a central location and just display an apt
-	  // error?
-	  bool in_debian=false;
-
-	  for(pkgCache::VerFileIterator vf=ver.FileList();
-	      !vf.end() && !in_debian; ++vf)
-	    if(!vf.File().end() && vf.File().Origin()!=NULL &&
-	       strcmp(vf.File().Origin(), "Debian")==0)
-	      in_debian=true;
+	  pkgCache::VerIterator ver=cmdline_find_ver(pkg,
+						     source, sourcestr);
 
-	  if(!in_debian)
+	  if(!ver.end())
 	    {
-	      _error->Error(_("%s is not an official Debian package, cannot display its changelog."), input.c_str());
-	      continue;
+	      // Move this to a central location and just display an
+	      // apt error?
+	      bool in_debian=false;
+
+	      for(pkgCache::VerFileIterator vf=ver.FileList();
+		  !vf.end() && !in_debian; ++vf)
+		if(!vf.File().end() && vf.File().Origin()!=NULL &&
+		   strcmp(vf.File().Origin(), "Debian")==0)
+		  in_debian=true;
+
+	      if(!in_debian)
+		{
+		  _error->Error(_("%s is not an official Debian package, cannot display its changelog."), input.c_str());
+		  continue;
+		}
 	    }
 
-	  pkg_changelog *cl=get_changelog(ver,
-					  gen_cmdline_download_progress(),
-					  500000);
-
-	  if(!cl)
-	    _error->Error(_("Couldn't find a changelog for %s"), input.c_str());
-	  else
+	  cl=get_changelog(ver,
+			   gen_cmdline_download_progress(),
+			   500000);
+	}
+      else
+	{
+	  changelog_entity ent;
+
+	  switch(source)
 	    {
-	      // Run the user's pager.
-	      system((string(pager)+" "+cl->get_filename()).c_str());
+	    case cmdline_version_cand:
+	      // In this case, pull the first one we see (not very
+	      // elegant, but finding the actual candidate is a bit
+	      // hard)
+	      {
+		pkgSrcRecords r(*apt_source_list);
+
+		pkgSrcRecords :: Parser *p(r.Find(package.c_str()));
+		while(p != NULL && p->Package() != package)
+		  p = r.Find(package.c_str());
+
+		if(p != NULL)
+		  ent = changelog_entity(package, p->Version(),
+					 p->Section());
+	      }
+
+	      break;
+
+	    case cmdline_version_archive:
+	      ent = find_src_archive(*apt_source_list,
+				     package, sourcestr);
+
+	      break;
+
+	    case cmdline_version_version:
+	      ent = find_src_ver(*apt_source_list, package, sourcestr);
 
-	      delete cl;
+	      break;
 	    }
+
+
+	  if(!ent.pkg.empty())
+	    cl = get_changelog_from_source(ent.pkg,
+					   ent.ver,
+					   ent.section,
+					   gen_cmdline_download_progress(),
+					   500000,
+					   ent.pkg);
+	}
+
+      if(!cl)
+	_error->Error(_("Couldn't find a changelog for %s"), input.c_str());
+      else
+	{
+	  // Run the user's pager.
+	  system((string(pager)+" "+cl->get_filename()).c_str());
+
+	  delete cl;
 	}
     }
 }

Modified: branches/aptitude-0.3/aptitude/src/generic/pkg_changelog.cc
==============================================================================
--- branches/aptitude-0.3/aptitude/src/generic/pkg_changelog.cc	(original)
+++ branches/aptitude-0.3/aptitude/src/generic/pkg_changelog.cc	Mon Jul 25 23:23:08 2005
@@ -84,10 +84,15 @@
   pkgRecords::Parser &rec=apt_package_records->Lookup(ver.FileList());
   string srcpkg=rec.SourcePkg().empty()?ver.ParentPkg().Name():rec.SourcePkg();
 
-  return get_changelog_from_source(srcpkg, status, PulseInterval, ver.ParentPkg().Name());
+  return get_changelog_from_source(srcpkg, ver.VerStr(), ver.Section(),
+				   status,
+				   PulseInterval,
+				   ver.ParentPkg().Name());
 }
 
 pkg_changelog *get_changelog_from_source(const string &srcpkg,
+					 const string &ver,
+					 const string &section,
 					 pkgAcquireStatus *status,
 					 int PulseInterval,
 					 const string &name)
@@ -126,19 +131,23 @@
   pkgSrcRecords src_recs(*apt_source_list);
   pkgSrcRecords::Parser *parser = src_recs.Find(srcpkg.c_str());
 
+  while(parser != NULL && parser->Version() != ver)
+    parser = src_recs.Find(srcpkg.c_str());
+
   if(parser == NULL)
     {
-      _error->Error(_("Unable to find source for package \"%s\""),
-		    srcpkg.c_str());
+      _error->Error(_("Unable to find source for package \"%s\" version \"%s\""),
+		    srcpkg.c_str(),
+		    ver.c_str());
       return NULL;
     }
 
-  string section=parser->Section();
+  string realsection;
 
   if(section.find('/')!=section.npos)
-    section.assign(section, 0, section.find('/'));
+    realsection.assign(section, 0, section.find('/'));
   else
-    section="main";
+    realsection.assign("main");
 
   string prefix;
 
@@ -147,20 +156,21 @@
   else
     prefix = srcpkg[0];
 
-  // packages.d.o uses a munged version number.
-  string verstr=parser->Version();
+  string realver;
 
-  if(verstr.find(':')!=verstr.npos)
-    verstr=string(verstr, verstr.find(':')+1);
+  if(ver.find(':')!=ver.npos)
+    realver.assign(ver, ver.find(':')+1, ver.npos);
+  else
+    realver=ver;
 
   snprintf(uribuf,
 	   sizeof(uribuf),
 	   "http://packages.debian.org/changelogs/pool/%s/%s/%s/%s_%s/changelog",
-	   section.c_str(),
+	   realsection.c_str(),
 	   prefix.c_str(),
 	   srcpkg.c_str(),
 	   srcpkg.c_str(),
-	   verstr.c_str());
+	   realver.c_str());
 
   pkgAcquire fetcher(status);
 

Modified: branches/aptitude-0.3/aptitude/src/generic/pkg_changelog.h
==============================================================================
--- branches/aptitude-0.3/aptitude/src/generic/pkg_changelog.h	(original)
+++ branches/aptitude-0.3/aptitude/src/generic/pkg_changelog.h	Mon Jul 25 23:23:08 2005
@@ -35,6 +35,8 @@
 
   pkg_changelog::pkg_changelog(const std::string &_filename);
   friend pkg_changelog *get_changelog_from_source(const std::string &,
+						  const std::string &,
+						  const std::string &,
 						  pkgAcquireStatus *,
 						  int,
 						  const std::string &);
@@ -51,6 +53,7 @@
 /** Return a changelog object for the given source package.
  *
  *  \param srcpkg the source package name
+ *  \param ver the version of the source package
  *  \param status the object to which the download status should be reported
  *  \param PulseInterval the interval at which to update the display
  *                       and poll for input
@@ -59,6 +62,8 @@
  *               was executed on)
  */
 pkg_changelog *get_changelog_from_source(const std::string &srcpkg,
+					 const std::string &ver,
+					 const std::string &section,
 					 pkgAcquireStatus *status,
 					 int PulseInterval,
 					 const std::string &name);



More information about the Aptitude-svn-commit mailing list