aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar David Leverton <levertond@googlemail.com> 2007-06-20 23:05:35 +0000
committerAvatar David Leverton <levertond@googlemail.com> 2007-06-20 23:05:35 +0000
commit1eb7ee74500817f588f8cb25c5ecd232b7e5f1ce (patch)
tree6a8065c2af3147633bc64d55eda99bf39c1e6f37
parentdbef84c191b6384aac5b30d6e79616cd875e57c7 (diff)
downloadpaludis-1eb7ee74500817f588f8cb25c5ecd232b7e5f1ce.tar.gz
paludis-1eb7ee74500817f588f8cb25c5ecd232b7e5f1ce.tar.xz
Make Unmerger handle multiple files with the same name, and allow subclasses to associate extra info with each file. Fixes: ticket:291
-rw-r--r--paludis/merger/unmerger.cc65
-rw-r--r--paludis/merger/unmerger.hh41
-rw-r--r--paludis/repositories/gentoo/vdb_unmerger.cc116
-rw-r--r--paludis/repositories/gentoo/vdb_unmerger.hh11
-rwxr-xr-xpaludis/repositories/gentoo/vdb_unmerger_TEST_setup.sh2
5 files changed, 148 insertions, 87 deletions
diff --git a/paludis/merger/unmerger.cc b/paludis/merger/unmerger.cc
index b8bf3af..ca1ea03 100644
--- a/paludis/merger/unmerger.cc
+++ b/paludis/merger/unmerger.cc
@@ -39,7 +39,7 @@ namespace paludis
{
UnmergerOptions options;
- std::map<std::string, EntryType> unmerge_set;
+ std::multimap<std::string, std::pair<EntryType, tr1::shared_ptr<Unmerger::ExtraInfo> > > unmerge_entries;
Implementation(const UnmergerOptions & o) :
options(o)
@@ -47,7 +47,7 @@ namespace paludis
}
};
- typedef std::map<std::string, EntryType>::reverse_iterator UnmergeListIterator;
+ typedef std::multimap<std::string, std::pair<EntryType, tr1::shared_ptr<Unmerger::ExtraInfo> > >::reverse_iterator UnmergeEntriesIterator;
}
UnmergerError::UnmergerError(const std::string & s) throw () :
@@ -55,6 +55,10 @@ UnmergerError::UnmergerError(const std::string & s) throw () :
{
}
+Unmerger::ExtraInfo::~ExtraInfo()
+{
+}
+
Unmerger::Unmerger(const UnmergerOptions & o) :
PrivateImplementationPattern<Unmerger>(new Implementation<Unmerger>(o))
{
@@ -65,10 +69,9 @@ Unmerger::~Unmerger()
}
void
-Unmerger::add_unmerge_entry(const std::string & f, EntryType et)
+Unmerger::add_unmerge_entry(const std::string & f, EntryType et, tr1::shared_ptr<ExtraInfo> ei)
{
- if (! _imp->unmerge_set.insert(std::make_pair(f, et)).second)
- throw UnmergerError("Entry '" + stringify(f) + "' already in the unmerge set");
+ _imp->unmerge_entries.insert(std::make_pair(f, std::make_pair(et, ei)));
}
void
@@ -81,25 +84,25 @@ Unmerger::unmerge()
("UNLINK_TARGET", stringify(_imp->options.root)))).max_exit_status)
throw UnmergerError("Unmerge from '" + stringify(_imp->options.root) + "' aborted by hook");
- for (UnmergeListIterator i(_imp->unmerge_set.rbegin()), i_end(_imp->unmerge_set.rend()) ; i != i_end ; ++i)
+ for (UnmergeEntriesIterator i(_imp->unmerge_entries.rbegin()), i_end(_imp->unmerge_entries.rend()) ; i != i_end ; ++i)
{
FSEntry f(i->first);
- switch (i->second)
+ switch (i->second.first)
{
case et_dir:
- unmerge_dir(f);
+ unmerge_dir(f, i->second.second);
continue;
case et_file:
- unmerge_file(f);
+ unmerge_file(f, i->second.second);
continue;
case et_sym:
- unmerge_sym(f);
+ unmerge_sym(f, i->second.second);
continue;
case et_misc:
- unmerge_misc(f);
+ unmerge_misc(f, i->second.second);
continue;
case et_nothing:
@@ -107,7 +110,7 @@ Unmerger::unmerge()
;
}
- throw InternalError(PALUDIS_HERE, "Unexpected entry_type '" + stringify((*i).second) + "'");
+ throw InternalError(PALUDIS_HERE, "Unexpected entry_type '" + stringify((*i).second.first) + "'");
}
if (0 != _imp->options.environment->perform_hook(extend_hook(
@@ -117,7 +120,7 @@ Unmerger::unmerge()
}
void
-Unmerger::unmerge_file(FSEntry & f) const
+Unmerger::unmerge_file(FSEntry & f, tr1::shared_ptr<ExtraInfo> ei) const
{
FSEntry f_real(_imp->options.root / f);
@@ -133,17 +136,17 @@ Unmerger::unmerge_file(FSEntry & f) const
else if (hr.output == "force")
{
display("<<< [force] " + stringify(f));
- unlink_file(f_real);
+ unlink_file(f_real, ei);
}
- else if (check_file(f))
+ else if (check_file(f, ei))
{
display("<<< " + stringify(f));
- unlink_sym(f_real);
+ unlink_sym(f_real, ei);
}
}
void
-Unmerger::unmerge_sym(FSEntry & f) const
+Unmerger::unmerge_sym(FSEntry & f, tr1::shared_ptr<ExtraInfo> ei) const
{
FSEntry f_real(_imp->options.root / f);
@@ -159,17 +162,17 @@ Unmerger::unmerge_sym(FSEntry & f) const
else if (hr.output == "force")
{
display("<<< [force] " + stringify(f));
- unlink_sym(f_real);
+ unlink_sym(f_real, ei);
}
- else if (check_sym(f))
+ else if (check_sym(f, ei))
{
display("<<< " + stringify(f));
- unlink_sym(f_real);
+ unlink_sym(f_real, ei);
}
}
void
-Unmerger::unmerge_dir(FSEntry & f) const
+Unmerger::unmerge_dir(FSEntry & f, tr1::shared_ptr<ExtraInfo> ei) const
{
FSEntry f_real(_imp->options.root / f);
@@ -182,15 +185,15 @@ Unmerger::unmerge_dir(FSEntry & f) const
throw UnmergerError("Unmerge of '" + stringify(f) + "' aborted by hook");
else if (hr.output == "skip")
display("--- [skip ] " + stringify(f));
- else if (check_dir(f))
+ else if (check_dir(f, ei))
{
display("<<< " + stringify(f));
- unlink_dir(f_real);
+ unlink_dir(f_real, ei);
}
}
void
-Unmerger::unmerge_misc(FSEntry & f) const
+Unmerger::unmerge_misc(FSEntry & f, tr1::shared_ptr<ExtraInfo> ei) const
{
FSEntry f_real(_imp->options.root / f);
@@ -206,17 +209,17 @@ Unmerger::unmerge_misc(FSEntry & f) const
else if (hr.output == "force")
{
display("<<< [force] " + stringify(f));
- unlink_misc(f_real);
+ unlink_misc(f_real, ei);
}
- else if (check_misc(f))
+ else if (check_misc(f, ei))
{
display("<<< " + stringify(f));
- unlink_misc(f_real);
+ unlink_misc(f_real, ei);
}
}
void
-Unmerger::unlink_file(FSEntry & f) const
+Unmerger::unlink_file(FSEntry & f, tr1::shared_ptr<ExtraInfo>) const
{
if (0 != _imp->options.environment->perform_hook(extend_hook(
Hook("unmerger_unlink_file_pre")
@@ -242,7 +245,7 @@ Unmerger::unlink_file(FSEntry & f) const
}
void
-Unmerger::unlink_sym(FSEntry & f) const
+Unmerger::unlink_sym(FSEntry & f, tr1::shared_ptr<ExtraInfo>) const
{
if (0 != _imp->options.environment->perform_hook(extend_hook(
Hook("unmerger_unlink_sym_pre")
@@ -258,7 +261,7 @@ Unmerger::unlink_sym(FSEntry & f) const
}
void
-Unmerger::unlink_dir(FSEntry & f) const
+Unmerger::unlink_dir(FSEntry & f, tr1::shared_ptr<ExtraInfo>) const
{
if (0 != _imp->options.environment->perform_hook(extend_hook(
Hook("unmerger_unlink_dir_pre")
@@ -274,7 +277,7 @@ Unmerger::unlink_dir(FSEntry & f) const
}
void
-Unmerger::unlink_misc(FSEntry & f) const
+Unmerger::unlink_misc(FSEntry & f, tr1::shared_ptr<ExtraInfo>) const
{
if (0 != _imp->options.environment->perform_hook(extend_hook(
Hook("unmerger_unlink_misc_pre")
diff --git a/paludis/merger/unmerger.hh b/paludis/merger/unmerger.hh
index 1733b43..0079a24 100644
--- a/paludis/merger/unmerger.hh
+++ b/paludis/merger/unmerger.hh
@@ -71,9 +71,24 @@ namespace paludis
///\}
/**
+ * Base class for extra information associated with a file
+ * to be unmerged.
+ *
+ * \ingroup grpunmerger
+ * \nosubgrouping
+ */
+ class PALUDIS_VISIBLE ExtraInfo
+ {
+ public:
+ virtual ~ExtraInfo();
+ };
+
+ friend class Implementation<Unmerger>;
+
+ /**
* Add entry to the unmerge set.
*/
- void add_unmerge_entry(const std::string &, EntryType);
+ void add_unmerge_entry(const std::string &, EntryType, tr1::shared_ptr<ExtraInfo>);
/**
* Populate the unmerge set.
@@ -88,32 +103,32 @@ namespace paludis
///\name Unmerge operations
///\{
- virtual void unmerge_file(FSEntry &) const;
- virtual void unmerge_dir(FSEntry &) const;
- virtual void unmerge_sym(FSEntry &) const;
- virtual void unmerge_misc(FSEntry &) const;
+ virtual void unmerge_file(FSEntry &, tr1::shared_ptr<ExtraInfo>) const;
+ virtual void unmerge_dir(FSEntry &, tr1::shared_ptr<ExtraInfo>) const;
+ virtual void unmerge_sym(FSEntry &, tr1::shared_ptr<ExtraInfo>) const;
+ virtual void unmerge_misc(FSEntry &, tr1::shared_ptr<ExtraInfo>) const;
///\}
///\name Check operations
///\{
- virtual bool check_file(const FSEntry &) const
+ virtual bool check_file(const FSEntry &, tr1::shared_ptr<ExtraInfo>) const
{
return true;
}
- virtual bool check_dir(const FSEntry &) const
+ virtual bool check_dir(const FSEntry &, tr1::shared_ptr<ExtraInfo>) const
{
return true;
}
- virtual bool check_sym(const FSEntry &) const
+ virtual bool check_sym(const FSEntry &, tr1::shared_ptr<ExtraInfo>) const
{
return true;
}
- virtual bool check_misc(const FSEntry &) const
+ virtual bool check_misc(const FSEntry &, tr1::shared_ptr<ExtraInfo>) const
{
return true;
}
@@ -123,10 +138,10 @@ namespace paludis
///\name Unlink operations
///\{
- virtual void unlink_file(FSEntry &) const;
- virtual void unlink_dir(FSEntry &) const;
- virtual void unlink_sym(FSEntry &) const;
- virtual void unlink_misc(FSEntry &) const;
+ virtual void unlink_file(FSEntry &, tr1::shared_ptr<ExtraInfo>) const;
+ virtual void unlink_dir(FSEntry &, tr1::shared_ptr<ExtraInfo>) const;
+ virtual void unlink_sym(FSEntry &, tr1::shared_ptr<ExtraInfo>) const;
+ virtual void unlink_misc(FSEntry &, tr1::shared_ptr<ExtraInfo>) const;
///\}
diff --git a/paludis/repositories/gentoo/vdb_unmerger.cc b/paludis/repositories/gentoo/vdb_unmerger.cc
index ef217cc..0ff229f 100644
--- a/paludis/repositories/gentoo/vdb_unmerger.cc
+++ b/paludis/repositories/gentoo/vdb_unmerger.cc
@@ -27,6 +27,7 @@ using namespace paludis;
#include <paludis/util/tokeniser.hh>
#include <paludis/util/log.hh>
#include <paludis/util/dir_iterator.hh>
+#include <paludis/util/destringify.hh>
#include <paludis/digests/md5.hh>
#include <paludis/hook.hh>
#include <paludis/util/private_implementation_pattern-impl.hh>
@@ -53,8 +54,6 @@ namespace paludis
std::list<std::string> config_protect;
std::list<std::string> config_protect_mask;
- std::multimap<std::string, std::string> extra_info;
-
Implementation(const VDBUnmergerOptions & o) :
options(o)
{
@@ -64,10 +63,60 @@ namespace paludis
std::back_inserter(config_protect_mask));
}
};
-
- typedef std::multimap<std::string, std::string>::iterator ExtraInfoIterator;
}
+class VDBUnmerger::FileExtraInfo :
+ public Unmerger::ExtraInfo
+{
+ public:
+ std::string _md5sum;
+ time_t _mtime;
+
+ FileExtraInfo(std::string md5sum, time_t mtime) :
+ _md5sum(md5sum),
+ _mtime(mtime)
+ {
+ }
+
+ virtual ~FileExtraInfo()
+ {
+ }
+};
+
+class VDBUnmerger::SymlinkExtraInfo :
+ public Unmerger::ExtraInfo
+{
+ public:
+ std::string _dest;
+ time_t _mtime;
+
+ SymlinkExtraInfo(std::string dest, time_t mtime) :
+ _dest(dest),
+ _mtime(mtime)
+ {
+ }
+
+ virtual ~SymlinkExtraInfo()
+ {
+ }
+};
+
+class VDBUnmerger::MiscExtraInfo :
+ public Unmerger::ExtraInfo
+{
+ public:
+ std::string _type;
+
+ MiscExtraInfo(std::string type) :
+ _type(type)
+ {
+ }
+
+ virtual ~MiscExtraInfo()
+ {
+ }
+};
+
VDBUnmerger::VDBUnmerger(const VDBUnmergerOptions & o) :
Unmerger(UnmergerOptions::create()
.environment(o.environment)
@@ -173,11 +222,10 @@ VDBUnmerger::populate_unmerge_set()
Log::get_instance()->message(ll_warning, lc_no_context, "Malformed VDB entry '" + line + "'");
else
{
- add_unmerge_entry(tokens.at(1), et_file);
-
- for (std::vector<std::string>::iterator i(next(tokens.begin(), 2)), i_end(tokens.end()) ;
- i != i_end ; ++i)
- _imp->extra_info.insert(std::make_pair(tokens.at(1), *i));
+ std::string md5sum(tokens.at(2));
+ time_t mtime(destringify<time_t>(tokens.at(3)));
+ tr1::shared_ptr<ExtraInfo> extra(new FileExtraInfo(md5sum, mtime));
+ add_unmerge_entry(tokens.at(1), et_file, extra);
}
}
@@ -205,11 +253,10 @@ VDBUnmerger::populate_unmerge_set()
Log::get_instance()->message(ll_warning, lc_no_context, "Malformed VDB entry '" + line + "'");
else
{
- add_unmerge_entry(tokens.at(1), et_sym);
-
- for (std::vector<std::string>::iterator i(next(tokens.begin(), 3)), i_end(tokens.end()) ;
- i != i_end ; ++i)
- _imp->extra_info.insert(std::make_pair(tokens.at(1), *i));
+ std::string dest(tokens.at(3));
+ time_t mtime(destringify<time_t>(tokens.at(4)));
+ tr1::shared_ptr<ExtraInfo> extra(new SymlinkExtraInfo(dest, mtime));
+ add_unmerge_entry(tokens.at(1), et_sym, extra);
}
}
else if ("misc" == tokens.at(0))
@@ -230,12 +277,9 @@ VDBUnmerger::populate_unmerge_set()
Log::get_instance()->message(ll_warning, lc_no_context, "Malformed VDB entry '" + line + "'");
else
{
- add_unmerge_entry(tokens.at(1), et_misc);
-
- _imp->extra_info.insert(std::make_pair(tokens.at(1), tokens.at(0)));
- for (std::vector<std::string>::iterator i(next(tokens.begin(), 2)), i_end(tokens.end()) ;
- i != i_end ; ++i)
- _imp->extra_info.insert(std::make_pair(tokens.at(1), *i));
+ std::string type(tokens.at(0));
+ tr1::shared_ptr<ExtraInfo> extra(new MiscExtraInfo(type));
+ add_unmerge_entry(tokens.at(1), et_misc, extra);
}
}
else if ("dir" == tokens.at(0))
@@ -253,11 +297,7 @@ VDBUnmerger::populate_unmerge_set()
Log::get_instance()->message(ll_warning, lc_no_context, "Malformed VDB entry '" + line + "'");
else
{
- add_unmerge_entry(tokens.at(1), et_dir);
-
- for (std::vector<std::string>::iterator i(next(tokens.begin(), 2)), i_end(tokens.end()) ;
- i != i_end ; ++i)
- _imp->extra_info.insert(std::make_pair(tokens.at(1), *i));
+ add_unmerge_entry(tokens.at(1), et_dir, tr1::shared_ptr<ExtraInfo>());
}
}
else
@@ -266,13 +306,13 @@ VDBUnmerger::populate_unmerge_set()
}
bool
-VDBUnmerger::check_file(const FSEntry & f) const
+VDBUnmerger::check_file(const FSEntry & f, tr1::shared_ptr<ExtraInfo> ei) const
{
- ExtraInfoIterator i(_imp->extra_info.lower_bound(stringify(f)));
+ tr1::shared_ptr<FileExtraInfo> fie(tr1::static_pointer_cast<FileExtraInfo>(ei));
if (! (_imp->options.root / f).is_regular_file())
display("--- [!type] " + stringify(f));
- else if (stringify((_imp->options.root / f).mtime()) != next(i)->second)
+ else if ((_imp->options.root / f).mtime() != fie->_mtime)
display("--- [!time] " + stringify(f));
else
{
@@ -283,7 +323,7 @@ VDBUnmerger::check_file(const FSEntry & f) const
stringify(_imp->options.root / f) + "'");
display("--- [!md5?] " + stringify(f));
}
- else if (MD5(md5_file).hexsum() != i->second)
+ else if (MD5(md5_file).hexsum() != fie->_md5sum)
display("--- [!md5 ] " + stringify(f));
else if (config_protected(_imp->options.root / f))
display("--- [cfgpr] " + stringify(f));
@@ -295,15 +335,15 @@ VDBUnmerger::check_file(const FSEntry & f) const
}
bool
-VDBUnmerger::check_sym(const FSEntry & f) const
+VDBUnmerger::check_sym(const FSEntry & f, tr1::shared_ptr<ExtraInfo> ei) const
{
- ExtraInfoIterator i(_imp->extra_info.lower_bound(stringify(f)));
+ tr1::shared_ptr<SymlinkExtraInfo> sie(tr1::static_pointer_cast<SymlinkExtraInfo>(ei));
if (! (_imp->options.root / f).is_symbolic_link())
display("--- [!type] " + stringify(f));
- else if (stringify((_imp->options.root / f).mtime()) != next(i)->second)
+ else if ((_imp->options.root / f).mtime() != sie->_mtime)
display("--- [!time] " + stringify(f));
- else if ((_imp->options.root / f).readlink() != i->second)
+ else if ((_imp->options.root / f).readlink() != sie->_dest)
display("--- [!dest] " + stringify(f));
else
return true;
@@ -312,13 +352,13 @@ VDBUnmerger::check_sym(const FSEntry & f) const
}
bool
-VDBUnmerger::check_misc(const FSEntry & f) const
+VDBUnmerger::check_misc(const FSEntry & f, tr1::shared_ptr<ExtraInfo> ei) const
{
- ExtraInfoIterator i(_imp->extra_info.lower_bound(stringify(f)));
+ tr1::shared_ptr<MiscExtraInfo> mie(tr1::static_pointer_cast<MiscExtraInfo>(ei));
- if ("fif" == i->second && ! (_imp->options.root / f).is_fifo())
+ if ("fif" == mie->_type && ! (_imp->options.root / f).is_fifo())
display("--- [!type] " + stringify(f));
- else if ("dev" == i->second && ! (_imp->options.root / f).is_device())
+ else if ("dev" == mie->_type && ! (_imp->options.root / f).is_device())
display("--- [!type] " + stringify(f));
else
return true;
@@ -327,7 +367,7 @@ VDBUnmerger::check_misc(const FSEntry & f) const
}
bool
-VDBUnmerger::check_dir(const FSEntry & f) const
+VDBUnmerger::check_dir(const FSEntry & f, tr1::shared_ptr<ExtraInfo>) const
{
if (! (_imp->options.root / f).is_directory())
display("--- [!type] " + stringify(f));
diff --git a/paludis/repositories/gentoo/vdb_unmerger.hh b/paludis/repositories/gentoo/vdb_unmerger.hh
index 4c6e967..5dfedaa 100644
--- a/paludis/repositories/gentoo/vdb_unmerger.hh
+++ b/paludis/repositories/gentoo/vdb_unmerger.hh
@@ -64,6 +64,9 @@ namespace paludis
{
private:
Implementation<VDBUnmerger> * _imp;
+ class FileExtraInfo;
+ class SymlinkExtraInfo;
+ class MiscExtraInfo;
protected:
bool config_protected(const FSEntry &) const;
@@ -73,10 +76,10 @@ namespace paludis
void display(const std::string &) const;
- bool check_file(const FSEntry &) const;
- bool check_dir(const FSEntry &) const;
- bool check_sym(const FSEntry &) const;
- bool check_misc(const FSEntry &) const;
+ bool check_file(const FSEntry &, tr1::shared_ptr<ExtraInfo>) const;
+ bool check_dir(const FSEntry &, tr1::shared_ptr<ExtraInfo>) const;
+ bool check_sym(const FSEntry &, tr1::shared_ptr<ExtraInfo>) const;
+ bool check_misc(const FSEntry &, tr1::shared_ptr<ExtraInfo>) const;
public:
///\name Basic operations
diff --git a/paludis/repositories/gentoo/vdb_unmerger_TEST_setup.sh b/paludis/repositories/gentoo/vdb_unmerger_TEST_setup.sh
index 34110b3..2930a48 100755
--- a/paludis/repositories/gentoo/vdb_unmerger_TEST_setup.sh
+++ b/paludis/repositories/gentoo/vdb_unmerger_TEST_setup.sh
@@ -37,7 +37,7 @@ rm file_bad_type
mkdir file_bad_type
make_file "bad_md5sum" "bad_md5sum"
-make_file "bad_mtime" "" "bad_mtime"
+make_file "bad_mtime" "" "123"
echo "obj /file_bad_entry foo" > ../CONTENTS/file_bad_entry
mkdir dir_ok