aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2007-07-24 15:34:08 +0000
committerAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2007-07-24 15:34:08 +0000
commit93e1fc3862dc0c0722161e9fec63fa0b136539b2 (patch)
tree90582d406855ff5fe84641acdc10e4f996057f21
parentc2123d403b0849b28848bb116bc84e65716c447f (diff)
downloadpaludis-93e1fc3862dc0c0722161e9fec63fa0b136539b2.tar.gz
paludis-93e1fc3862dc0c0722161e9fec63fa0b136539b2.tar.xz
Don't die on stale cache files. Fixes: ticket:306
-rw-r--r--paludis/repositories/e/e_repository_TEST.cc41
-rwxr-xr-xpaludis/repositories/e/e_repository_TEST_setup.sh35
-rw-r--r--paludis/repositories/e/ebuild_flat_metadata_cache.cc109
3 files changed, 148 insertions, 37 deletions
diff --git a/paludis/repositories/e/e_repository_TEST.cc b/paludis/repositories/e/e_repository_TEST.cc
index d37e7da..a9f3066 100644
--- a/paludis/repositories/e/e_repository_TEST.cc
+++ b/paludis/repositories/e/e_repository_TEST.cc
@@ -489,11 +489,6 @@ namespace test_cases
{
ERepositoryMetadataUncachedTest() : TestCase("metadata uncached") { }
- bool skip() const
- {
- return ! getenv_with_default("SANDBOX_ON", "").empty();
- }
-
void run()
{
for (int opass = 1 ; opass <= 3 ; ++opass)
@@ -549,6 +544,42 @@ namespace test_cases
}
} test_e_repository_metadata_uncached;
+ struct ERepositoryMetadataStaleTest : TestCase
+ {
+ ERepositoryMetadataStaleTest() : TestCase("metadata stale") { }
+
+ void run()
+ {
+ for (int opass = 1 ; opass <= 3 ; ++opass)
+ {
+ TestMessageSuffix opass_suffix("opass=" + stringify(opass), true);
+
+ TestEnvironment env;
+ tr1::shared_ptr<Map<std::string, std::string> > keys(
+ new Map<std::string, std::string>);
+ keys->insert("format", "ebuild");
+ keys->insert("names_cache", "/var/empty");
+ keys->insert("write_cache", "e_repository_TEST_dir/repo7/metadata/cache");
+ keys->insert("location", "e_repository_TEST_dir/repo7");
+ keys->insert("profiles", "e_repository_TEST_dir/repo7/profiles/profile");
+ tr1::shared_ptr<ERepository> repo(make_ebuild_repository(&env, keys));
+ env.package_database()->add_repository(1, repo);
+
+ for (int pass = 1 ; pass <= 3 ; ++pass)
+ {
+ TestMessageSuffix pass_suffix("pass=" + stringify(pass), true);
+
+ tr1::shared_ptr<const PackageID> id1(*env.package_database()->query(query::Matches(
+ PackageDepSpec("=cat-one/stale-pkg-1", pds_pm_unspecific)), qo_require_exactly_one)->begin());
+
+ TEST_CHECK(id1->end_metadata() != id1->find_metadata("EAPI"));
+ TEST_CHECK(id1->short_description_key());
+ TEST_CHECK_EQUAL(id1->short_description_key()->value(), "The Generated Description");
+ }
+ }
+ }
+ } test_e_repository_metadata_stale;
+
/**
* \test Test ERepository unparsable metadata.
*
diff --git a/paludis/repositories/e/e_repository_TEST_setup.sh b/paludis/repositories/e/e_repository_TEST_setup.sh
index 4e45de9..6754ca2 100755
--- a/paludis/repositories/e/e_repository_TEST_setup.sh
+++ b/paludis/repositories/e/e_repository_TEST_setup.sh
@@ -122,7 +122,7 @@ cd ..
mkdir -p repo7/{eclass,distfiles,profiles/profile} || exit 1
-mkdir -p repo7/cat-one/pkg-{one,two} || exit 1
+mkdir -p repo7/cat-one/{stale-pkg,pkg-{one,two}} || exit 1
mkdir -p repo7/metadata/cache/cat-{one,two}
cd repo7 || exit 1
echo "test-repo-7" > profiles/repo_name || exit 1
@@ -156,11 +156,42 @@ END
cat <<END > eclass/mine.eclass
DEPEND="bar/baz"
END
+cat <<END > eclass/stale.eclass
+END
cat <<END > cat-one/pkg-two/pkg-two-1.ebuild || exit 1
i am a fish
END
-cd ..
+cat <<END > cat-one/stale-pkg/stale-pkg-1.ebuild || exit 1
+inherit stale
+DESCRIPTION="The Generated Description"
+HOMEPAGE="http://example.com/"
+SRC_URI=""
+SLOT="0"
+IUSE=""
+LICENSE="GPL-2"
+KEYWORDS="test"
+DEPEND=""
+END
+cat <<END > metadata/cache/cat-one/stale-pkg-1
+the/depend
+the/rdepend
+the-slot
+the-src-uri
+the-restrict
+the-homepage
+the-license
+The Stale Description
+the-keywords
+stale
+the-iuse
+unused
+the/pdepend
+the/provide
+0
+END
+touch -t 199901010101 metadata/cache/cat-one/stale-pkg-1 || exit 2
+cd ..
mkdir -p repo8/{eclass,distfiles,profiles/profile} || exit 1
mkdir -p repo8/{cat-one/{pkg-one,pkg-both},cat-two/{pkg-two,pkg-both}} || exit 1
diff --git a/paludis/repositories/e/ebuild_flat_metadata_cache.cc b/paludis/repositories/e/ebuild_flat_metadata_cache.cc
index cc4e573..56678c0 100644
--- a/paludis/repositories/e/ebuild_flat_metadata_cache.cc
+++ b/paludis/repositories/e/ebuild_flat_metadata_cache.cc
@@ -25,11 +25,12 @@
#include <paludis/util/set.hh>
#include <paludis/repositories/e/dep_spec_pretty_printer.hh>
#include <paludis/repositories/e/eapi.hh>
+#include <paludis/util/tr1_functional.hh>
+#include <libwrapiter/libwrapiter_forward_iterator.hh>
#include <fstream>
#include <set>
#include <list>
-#include <paludis/util/tr1_functional.hh>
-#include <libwrapiter/libwrapiter_forward_iterator.hh>
+#include <vector>
#include <functional>
#include <algorithm>
@@ -54,37 +55,85 @@ EbuildFlatMetadataCache::load(const tr1::shared_ptr<const EbuildID> & id)
Context context("When loading version metadata from '" + stringify(_filename) + "':");
std::ifstream cache(stringify(_filename).c_str());
- std::string line;
if (cache)
{
- std::getline(cache, line); id->load_build_depend("DEPEND", "Build depend", line);
- std::getline(cache, line); id->load_run_depend("RDEPEND", "Run depend", line);
- std::getline(cache, line); id->set_slot(SlotName(line));
- std::getline(cache, line); id->load_src_uri("SRC_URI", "Source URI", line);
- std::getline(cache, line); id->load_restrict("RESTRICT", "Restrictions", line);
- std::getline(cache, line); id->load_homepage("HOMEPAGE", "Homepage", line);
- std::getline(cache, line); id->load_license("LICENSE", "License", line);
- std::getline(cache, line); id->load_short_description("DESCRIPTION", "Description", line);
- std::getline(cache, line); id->load_keywords("KEYWORDS", "Keywords", line);
- std::getline(cache, line); id->load_inherited("INHERITED", "Inherited", line);
- std::getline(cache, line); id->load_iuse("IUSE", "Used USE flags", line);
- std::getline(cache, line);
- std::getline(cache, line); id->load_post_depend("PDEPEND", "Post depend", line);
- std::getline(cache, line); id->load_provide("PROVIDE", "Provides", line);
- std::getline(cache, line); id->set_eapi(line);
-
- // check mtimes
- time_t cache_time(std::max(_master_mtime, _filename.mtime()));
- bool ok = _ebuild.mtime() <= cache_time &&
- id->inherited_key()->value()->end() == std::find_if(id->inherited_key()->value()->begin(), id->inherited_key()->value()->end(),
- tr1::bind(std::greater<time_t>(), tr1::bind(
- tr1::mem_fn(&EclassMtimes::mtime), _eclass_mtimes.get(), _1), cache_time));
-
- if (! ok)
- Log::get_instance()->message(ll_warning, lc_no_context) << "Stale cache file at '"
- << _filename << "'";
- return ok;
+ std::vector<std::string> lines;
+ std::string line;
+ while (std::getline(cache, line))
+ lines.push_back(line);
+
+ try
+ {
+ if (lines.size() >= 15)
+ {
+ id->set_eapi(lines[14]);
+ bool ok(true);
+
+ if (id->eapi()->supported)
+ {
+ const EAPIEbuildMetadataVariables & m(*id->eapi()->supported->ebuild_metadata_variables);
+
+ if (! lines[9].empty())
+ {
+ time_t cache_time(std::max(_master_mtime, _filename.mtime()));
+ std::set<std::string> tokens;
+ WhitespaceTokeniser::get_instance()->tokenise(lines[9], std::inserter(tokens, tokens.begin()));
+ ok = _ebuild.mtime() <= cache_time &&
+ tokens.end() == std::find_if(tokens.begin(), tokens.end(),
+ tr1::bind(std::greater<time_t>(), tr1::bind(
+ tr1::mem_fn(&EclassMtimes::mtime), _eclass_mtimes.get(), _1), cache_time));
+ }
+
+ if (ok)
+ {
+ if (! m.metadata_build_depend.empty())
+ id->load_build_depend(m.metadata_build_depend, m.description_build_depend, lines[0]);
+ if (! m.metadata_run_depend.empty())
+ id->load_run_depend(m.metadata_run_depend, m.description_run_depend, lines[1]);
+ id->set_slot(SlotName(lines[2]));
+ if (! m.metadata_src_uri.empty())
+ id->load_src_uri(m.metadata_src_uri, m.description_src_uri, lines[3]);
+ if (! m.metadata_restrict.empty())
+ id->load_restrict(m.metadata_restrict, m.description_restrict, lines[4]);
+ if (! m.metadata_homepage.empty())
+ id->load_homepage(m.metadata_homepage, m.description_homepage, lines[5]);
+ if (! m.metadata_license.empty())
+ id->load_license(m.metadata_license, m.description_license, lines[6]);
+ if (! m.metadata_description.empty())
+ id->load_short_description(m.metadata_description, m.description_description, lines[7]);
+ if (! m.metadata_keywords.empty())
+ id->load_keywords(m.metadata_keywords, m.description_keywords, lines[8]);
+ if (! m.metadata_inherited.empty())
+ id->load_inherited(m.metadata_inherited, m.description_inherited, lines[9]);
+ if (! m.metadata_iuse.empty())
+ id->load_iuse(m.metadata_iuse, m.description_iuse, lines[10]);
+ /* 11 no longer used */
+ if (! m.metadata_pdepend.empty())
+ id->load_post_depend(m.metadata_pdepend, m.description_pdepend, lines[12]);
+ if (! m.metadata_provide.empty())
+ id->load_provide(m.metadata_provide, m.description_provide, lines[13]);
+ }
+ }
+
+ if (! ok)
+ Log::get_instance()->message(ll_warning, lc_no_context) << "Stale cache file at '"
+ << _filename << "'";
+ return ok;
+ }
+ else
+ {
+ Log::get_instance()->message(ll_warning, lc_no_context) << "Incomplete cache file at '"
+ << _filename << "'";
+ return false;
+ }
+ }
+ catch (const Exception & e)
+ {
+ Log::get_instance()->message(ll_warning, lc_no_context) << "Not using cache file at '"
+ << _filename << "' due to exception '" << e.message() << "' (" << e.what() << ")";
+ return false;
+ }
}
else
{