summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS3
-rw-r--r--src/cmdline/cmdline_changelog.cc18
-rw-r--r--src/generic/apt/pkg_changelog.cc114
-rw-r--r--src/generic/apt/pkg_changelog.h18
-rw-r--r--src/view_changelog.cc14
5 files changed, 114 insertions, 53 deletions
diff --git a/NEWS b/NEWS
index 9362657b..9af97aa6 100644
--- a/NEWS
+++ b/NEWS
@@ -126,6 +126,9 @@ behaviour is desirable for two reasons:
in Debian Policy § 11.1 “Architecture specification
strings”.
+ * [all]: Support downloading changelogs for packages on
+ third-party sites by guessing the URI. (LP: #563155)
+
- Minor bugs:
* handle "-qq" like other apt-utils
diff --git a/src/cmdline/cmdline_changelog.cc b/src/cmdline/cmdline_changelog.cc
index 966b9273..370301af 100644
--- a/src/cmdline/cmdline_changelog.cc
+++ b/src/cmdline/cmdline_changelog.cc
@@ -230,7 +230,7 @@ void set_name(temp::name n, temp::name *target)
term_metrics);
boost::shared_ptr<aptitude::apt::changelog_info>
- info = aptitude::apt::changelog_info::create(srcpkg, ver, section, name);
+ info = aptitude::apt::changelog_info::guess(srcpkg, ver, section, name);
get_changelog(info,
callbacks,
@@ -316,22 +316,6 @@ void do_cmdline_changelog(const vector<string> &packages,
if(!ver.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;
-
- if(!in_debian)
- {
- _error->Error(_("%s is not an official Debian package, cannot display its changelog."), input.c_str());
- continue;
- }
-
get_changelog(ver, filename, term_metrics);
}
}
diff --git a/src/generic/apt/pkg_changelog.cc b/src/generic/apt/pkg_changelog.cc
index d425a260..192d3e56 100644
--- a/src/generic/apt/pkg_changelog.cc
+++ b/src/generic/apt/pkg_changelog.cc
@@ -85,15 +85,89 @@ namespace aptitude
}
}
+ std::string get_changelog_uri(const std::string &path)
+ {
+ string server = _config->Find("APT::Changelogs::Server",
+ "http://packages.debian.org/changelogs");
+
+ return cw::util::ssprintf("%s/%s/changelog",
+ server.c_str(),
+ path.c_str());
+ }
+
+ /* Construct a changelog file path for third party sites that do
+ * not use packages.debian.org/changelogs
+ * This simply uses the ArchiveURI() of the source pkg and looks for
+ * a .changelog file there.
+ */
+ bool guess_third_party_changelog_uri(pkgCache::VerIterator ver,
+ const std::string &path,
+ std::string &out_uri)
+ {
+ // guess uri for third-party packages
+ pkgCache::VerFileIterator vf = ver.FileList();
+ pkgCache::PkgFileIterator pf = vf.File();
+ pkgIndexFile *index;
+ if(apt_source_list->FindIndex(pf, index) == false)
+ return false;
+
+ out_uri = index->ArchiveURI(path + ".changelog");
+ return true;
+ }
+
boost::shared_ptr<changelog_info>
changelog_info::create(const std::string &source_package,
const std::string &source_version,
- const std::string &path,
+ const std::vector<std::string> &uri_list,
const std::string &display_name)
{
return boost::make_shared<changelog_info>(source_package,
source_version,
- path,
+ uri_list,
+ display_name);
+ }
+
+ boost::shared_ptr<changelog_info>
+ changelog_info::guess(const std::string &source_package,
+ const std::string &source_version,
+ const std::string &section,
+ const std::string &display_name)
+ {
+ string realsection;
+ const string::size_type slashfound = section.find('/');
+ if(slashfound != section.npos)
+ realsection.assign(section, 0, slashfound);
+ else
+ realsection.assign("main");
+
+ string prefix;
+ if(source_package.size() > 3
+ && source_package.compare(0, 3, "lib") == 0)
+ prefix.assign(source_package, 0, 4);
+ else
+ prefix.assign(source_package, 0, 1);
+
+ string realver = StripEpoch(source_version);
+
+ vector<string> uri_list;
+
+ string path;
+ path = cw::util::ssprintf("pool/%s/%s/%s/%s_%s",
+ realsection.c_str(),
+ prefix.c_str(),
+ source_package.c_str(),
+ source_package.c_str(),
+ realver.c_str());
+
+ uri_list.push_back(get_changelog_uri(path));
+
+ LOG_TRACE(Loggers::getAptitudeChangelog(),
+ "Getting the changelog of the source package "
+ << source_package << " " << source_version);
+
+ return boost::make_shared<changelog_info>(source_package,
+ source_version,
+ uri_list,
display_name);
}
@@ -123,14 +197,22 @@ namespace aptitude
path = flNotFile(rec.FileName());
path += source_package + "_" + StripEpoch(source_version);
+ vector<string> uri_list;
+
+ uri_list.push_back(get_changelog_uri(path));
+
+ string third_party_uri;
+ if(guess_third_party_changelog_uri(ver, path, third_party_uri))
+ uri_list.push_back(third_party_uri);
+
LOG_TRACE(Loggers::getAptitudeChangelog(),
"For " << ver.ParentPkg().Name()
<< " " << ver.VerStr() << ", getting the changelog of the source package "
- << source_package << " " << source_version << " from " << path);
+ << source_package << " " << source_version);
return boost::make_shared<changelog_info>(source_package,
source_version,
- path,
+ uri_list,
ver.ParentPkg().Name());
}
@@ -391,8 +473,6 @@ namespace aptitude
<< req.get_info()->get_source_package()
<< ", source_version = "
<< req.get_info()->get_source_version()
- << ", path = "
- << req.get_info()->get_path()
<< ", display_name = "
<< req.get_info()->get_display_name()
<< ", download = 0x"
@@ -442,7 +522,7 @@ namespace aptitude
const string source_package(info.get_source_package());
const string source_version(info.get_source_version());
- const string path(info.get_path());
+ const vector<string> uri_list(info.get_uri_list());
const string name(info.get_display_name());
const string short_description = cw::util::ssprintf(_("Changelog of %s"), name.c_str());
@@ -526,15 +606,17 @@ namespace aptitude
}
}
- string server = _config->Find("APT::Changelogs::Server",
- "http://packages.debian.org/changelogs");
- string uri = cw::util::ssprintf("%s/%s/changelog", server.c_str(), path.c_str());
- LOG_TRACE(logger,
- "Adding " << uri
- << " as a URI for the changelog of " << source_package << " " << source_version);
-
- download.push_back(uri);
-
+ for(vector<string>::const_iterator uri = uri_list.begin();
+ uri != uri_list.end();
+ ++uri)
+ {
+ LOG_TRACE(logger,
+ "Adding " << (*uri)
+ << " as a URI for the changelog of " << source_package
+ << " " << source_version);
+
+ download.push_back(*uri);
+ }
LOG_TRACE(logger,
"Starting to download " << short_description);
diff --git a/src/generic/apt/pkg_changelog.h b/src/generic/apt/pkg_changelog.h
index a0748177..cf4ffa55 100644
--- a/src/generic/apt/pkg_changelog.h
+++ b/src/generic/apt/pkg_changelog.h
@@ -56,7 +56,7 @@ namespace aptitude
{
const std::string source_package;
const std::string source_version;
- const std::string path;
+ const std::vector<std::string> uri_list;
const std::string display_name;
public:
@@ -66,11 +66,11 @@ namespace aptitude
*/
changelog_info(const std::string &_source_package,
const std::string &_source_version,
- const std::string &_path,
+ const std::vector<std::string> &_uri_list,
const std::string &_display_name)
: source_package(_source_package),
source_version(_source_version),
- path(_path),
+ uri_list(_uri_list),
display_name(_display_name)
{
}
@@ -78,9 +78,15 @@ namespace aptitude
static boost::shared_ptr<changelog_info>
create(const std::string &source_package,
const std::string &source_version,
- const std::string &path,
+ const std::vector<std::string> &uri_list,
const std::string &display_name);
+ static boost::shared_ptr<changelog_info>
+ guess(const std::string &source_package,
+ const std::string &source_version,
+ const std::string &section,
+ const std::string &display_name);
+
/** \brief Create a changelog_info structure that describes the
* changelog of the given package version.
*
@@ -94,8 +100,8 @@ namespace aptitude
const std::string &get_source_package() const { return source_package; }
/** \brief Retrieve the name of the changelog's source version. */
const std::string &get_source_version() const { return source_version; }
- /** \brief Retrieve the path string for changelog url construction. */
- const std::string &get_path() const { return path; }
+ /** \brief Retrieve the list of URIs to try, in order. */
+ const std::vector<std::string> &get_uri_list() const { return uri_list; }
/** \brief Retrieve the display name of the changelog's package.
*
* This is the name that should be displayed to the user when,
diff --git a/src/view_changelog.cc b/src/view_changelog.cc
index ae7ed465..0a3d7498 100644
--- a/src/view_changelog.cc
+++ b/src/view_changelog.cc
@@ -385,8 +385,6 @@ public:
void view_changelog(pkgCache::VerIterator ver)
{
- bool in_debian=false;
-
string pkgname = ver.ParentPkg().Name();
@@ -404,18 +402,6 @@ void view_changelog(pkgCache::VerIterator ver)
}
// TODO: add a configurable association between origins and changelog URLs.
- 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)
- {
- show_message(_("You can only view changelogs of official Debian packages."),
- NULL, cw::get_style("Error"));
- return;
- }
boost::shared_ptr<changelog_callbacks> callbacks =
boost::make_shared<changelog_callbacks>(ver.ParentPkg().Name(),