[Debtags-commits] [svn] r890 - debtags/trunk/src

Enrico Zini debtags-commits@lists.alioth.debian.org
Fri, 17 Jun 2005 18:44:13 +0000


Author: enrico
Date: Fri Jun 17 18:44:13 2005
New Revision: 890

Modified:
   debtags/trunk/src/debtags.cc
   debtags/trunk/src/instantiations.cc
Log:
Ported to using DebtagsSimple instead of Environment

Modified: debtags/trunk/src/debtags.cc
==============================================================================
--- debtags/trunk/src/debtags.cc	(original)
+++ debtags/trunk/src/debtags.cc	Fri Jun 17 18:44:13 2005
@@ -27,7 +27,6 @@
 #define PACKAGE_VERSION "unknown"
 #endif
 
-#include <debtags/Environment.h>
 #include <debtags/Consumer.h>
 #include <debtags/Package.h>
 #include <debtags/PackageSet.h>
@@ -41,6 +40,7 @@
 #include <debtags/Paths.h>
 #include <debtags/BasicPackageMatcher.h>
 #include <debtags/TagToFacet.h>
+#include <debtags/DebtagsSimple.h>
 #include <tagcoll/FilterChain.h>
 #include <tagcoll/Implications.h>
 #include <tagcoll/TagcollFilter.h>
@@ -86,12 +86,22 @@
 using namespace std;
 using namespace Debtags;
 
+/*
 void wantTagDatabase() throw ()
 {
 	if (!Debtags::Environment::get().hasTagDatabase())
 		fatal_error(
 				"The tag database has not yet been generated: you need to run \"debtags update\" (as root) before using the package tags\n");
 }
+*/
+
+template<class ITEM>
+void wantTagDatabase(DebtagsSimple<ITEM>& debtags) throw ()
+{
+	if (!debtags.hasTagDatabase())
+		fatal_error(
+				"The tag database has not yet been generated: you need to run \"debtags update\" (as root) before using the package tags\n");
+}
 
 void readCollection(const string& file, TagcollConsumer<string, string>& output)
 	throw (FileException, ParserException)
@@ -109,18 +119,21 @@
 	}
 }
 
-void readCollection(const string& file, TagcollConsumer<Package, Tag>& output)
+template<class ITEM, class TAG>
+void readCollection(Tagcoll::Serializer<ITEM, TAG>& serializer,
+					const string& file,
+					TagcollConsumer<ITEM, TAG>& output)
 	throw (FileException, ParserException)
 {
 	if (file == "-")
 	{
 		StdioParserInput input(stdin, "<stdin>");
-		TextFormat<Package, Tag>::parse(input, Debtags::Environment::get().serializer(), output);
+		TextFormat<ITEM, TAG>::parse(input, serializer, output);
 	}
 	else
 	{
 		StdioParserInput input(file);
-		TextFormat<Package, Tag>::parse(input, Debtags::Environment::get().serializer(), output);
+		TextFormat<ITEM, TAG>::parse(input, serializer, output);
 	}
 }
 
@@ -237,6 +250,7 @@
 };
 
 // Score tags by how many installed packages are there with them
+// Needs package to see if it's installed
 class TagsScorer : public map<Tag, int>, public TagcollConsumer<Package, Tag>
 {
 public:
@@ -273,6 +287,7 @@
 	}
 };
 
+// Needs package for TagsScorer
 class PackageScorer : public map<int, Package>, public TagcollConsumer<Package, Tag>
 {
 protected:
@@ -319,6 +334,7 @@
 		{ (*this) += items; }
 };
 
+// Needs Package to print short description
 class PackagePrinter : public Debtags::PackageConsumer, public Tagcoll::TagcollConsumer<Package, Tag>
 {
 protected:
@@ -346,18 +362,19 @@
 	int count() const throw () { return _count; }
 };
 
-class FacetcollPrinter : public Tagcoll::TagcollConsumer<Package, Facet>
+template<class ITEM>
+class FacetcollPrinter : public Tagcoll::TagcollConsumer<ITEM, Facet>
 {
 public:
 	virtual ~FacetcollPrinter() throw () {}
 
-	virtual void consume(const Package& item) throw ()
+	virtual void consume(const ITEM& item) throw ()
 	{
-		printf("%.*s\n", PFSTR(item.name()));
+		printf("%.*s\n", PFSTR(item));
 	}
-	virtual void consume(const Package& item, const OpSet<Facet>& tags) throw ()
+	virtual void consume(const ITEM& item, const OpSet<Facet>& tags) throw ()
 	{
-		printf("%.*s: ", PFSTR(item.name()));
+		printf("%.*s: ", PFSTR(item));
 		for (OpSet<Facet>::const_iterator i = tags.begin();
 				i != tags.end(); i++)
 			if (i == tags.begin())
@@ -369,6 +386,26 @@
 	}
 };
 
+template<>
+void FacetcollPrinter<Package>::consume(const Package& item) throw ()
+{
+	printf("%.*s\n", PFSTR(item.name()));
+}
+template<>
+void FacetcollPrinter<Package>::consume(const Package& item, const OpSet<Facet>& tags) throw ()
+{
+	printf("%.*s: ", PFSTR(item.name()));
+	for (OpSet<Facet>::const_iterator i = tags.begin();
+			i != tags.end(); i++)
+		if (i == tags.begin())
+			printf("%.*s", PFSTR(i->name()));
+		else
+			printf(", %.*s", PFSTR(i->name()));
+	printf("\n");
+
+}
+
+
 /*
 class ItemPrinter : public Tagcoll::TagcollConsumer<string, string>
 {
@@ -386,6 +423,7 @@
 };
 */
 
+// Needs Package to see if it's installed
 class TODOFilter : public Tagcoll::TagcollFilter<Package, Tag>
 {
 protected:
@@ -393,8 +431,8 @@
 	Tagexpr* expr;
 
 public:
-	TODOFilter() throw (ConsistencyCheckException)
-		: ser(Debtags::Environment::get().serializer()), expr(0)
+	TODOFilter(Serializer<Package, Tag>& ser) throw (ConsistencyCheckException)
+		: ser(ser), expr(0)
 	{
 		expr = TagexprParser::instance()->parse("special::not-yet-tagged*");
 		if (expr == 0)
@@ -418,15 +456,17 @@
 	}
 };
 
-class ExprCollector : public Tagcoll::TagcollConsumer<Package, Tag>, public PackageSet
+template<class ITEM>
+class ExprCollector : public Tagcoll::TagcollConsumer<ITEM, Tag>, public PackageSet
 {
 protected:
-	Serializer<Package, Tag>& ser;
+	Serializer<ITEM, Tag>& ser;
 	Tagexpr* expr;
 
 public:
-	ExprCollector(const std::string& expression) throw (ConsistencyCheckException)
-		: ser(Debtags::Environment::get().serializer()), expr(0)
+	ExprCollector(Serializer<ITEM, Tag>& ser, const std::string& expression)
+		throw (ConsistencyCheckException)
+		: ser(ser), expr(0)
 	{
 		expr = TagexprParser::instance()->parse(expression);
 		if (expr == 0)
@@ -450,6 +490,8 @@
 	}
 };
 
+// Might need package in the future to count stats about installed packages
+// TODO: count stats about installed packages
 class StatsCollector : public Tagcoll::TagcollConsumer<Package, Tag>
 {
 protected:
@@ -463,8 +505,8 @@
 	int stat_complete;
 
 public:
-	StatsCollector() throw (ConsistencyCheckException)
-		: ser(Debtags::Environment::get().serializer()), expr(0), stat_seen(0),
+	StatsCollector(Serializer<Package, Tag>& ser) throw (ConsistencyCheckException)
+		: ser(ser), expr(0), stat_seen(0),
 		  stat_onlynyt(0), stat_nyt(0), stat_notags(0), stat_tagged(0), stat_complete(0)
 	{
 		expr = TagexprParser::instance()->parse("special::not-yet-tagged*");
@@ -524,59 +566,67 @@
 	int count() const throw () { return _count; }
 };
 
-OpSet<Package> getItems(HierarchyNode<Package, Facet>* node)
+template<class ITEM>
+OpSet<ITEM> getItems(HierarchyNode<ITEM, Facet>* node)
 {
-	OpSet<Package> items = node->getItems();
+	OpSet<ITEM> items = node->getItems();
 	
-	for (HierarchyNode<Package, Facet>::iterator i = node->begin();
+	for (typename HierarchyNode<ITEM, Facet>::iterator i = node->begin();
 			i != node->end(); i++)
 		items += getItems(*i);
 
 	return items;
 }
 
-class MICollector : public TagcollConsumer<Package, Facet>
+// Collect items that are making a potential implication between 'existing' and
+// 'missing' fail.  Basically, collect all items that have facet 'existing' but
+// not facet 'missing'
+template<class ITEM>
+class MICollector : public TagcollConsumer<ITEM, Facet>
 {
 protected:
 	const Facet& existing;
 	const Facet& missing;
-	PackageSet found;
+	OpSet<ITEM> found;
 public:
 	MICollector(const Facet& existing, const Facet& missing) : existing(existing), missing(missing) {}
 	virtual ~MICollector() throw() {}
 
-	virtual void consume(const Package& item) throw () {}
-	virtual void consume(const OpSet<Package>& items) throw () {}
+	virtual void consume(const ITEM& item) throw () {}
+	virtual void consume(const OpSet<ITEM>& items) throw () {}
 
-	virtual void consume(const Package& item, const OpSet<Facet>& tags) throw ()
+	virtual void consume(const ITEM& item, const OpSet<Facet>& tags) throw ()
 	{
 		if (tags.contains(existing) && !tags.contains(missing))
 			found += item;
 	}
 
-	virtual void consume(const OpSet<Package>& items, const OpSet<Facet>& tags) throw ()
+	virtual void consume(const OpSet<ITEM>& items, const OpSet<Facet>& tags) throw ()
 	{
 		if (tags.contains(existing) && !tags.contains(missing))
 			found += items;
 	}
 
-	const PackageSet& getFound() const throw () { return found; }
+	const OpSet<ITEM>& getFound() const throw () { return found; }
 };
 
 
-
-PackageSet getMissedImplications(const TaggedCollection<Package, Facet>& coll,
+template<class ITEM>
+PackageSet getMissedImplications(const TaggedCollection<ITEM, Facet>& coll,
 									const Facet& existing, const Facet& missing)
 {
-	MICollector mc(existing, missing);
+	MICollector<ITEM> mc(existing, missing);
 	coll.output(mc);
 	return mc.getFound();
 }
 
+// Needs Package to get the short description
+// TODO: just instantiate the package when it actually needs the short
+// description
 class ReportMaker
 {
 protected:
-	const Debtags::Vocabulary& voc;
+	Debtags::DebtagsSimple<Package>& debtags;
 	PackageSet mentionedPackages;
 	unsigned int itemsPerGroup;
 
@@ -639,7 +689,7 @@
 
 		TagCollection<Package, Facet> coll;
 		TagToFacet<Package> tagStripper(&coll);
-		Debtags::Environment::get().tagDB().outputPatched(tagStripper);
+		debtags.tagDB().outputPatched(tagStripper);
 		Facet f;
 		SmartHierarchyNode<Package, Facet> node(f, coll, 0);
 
@@ -683,8 +733,8 @@
 	{
 		out(".. _"); out(expr); out(":\n\n");
 		out(descr);
-		ExprCollector miss(expr);
-		Debtags::Environment::get().tagDB().outputPatched(miss);
+		ExprCollector<Package> miss(debtags.serializer(), expr);
+		debtags.tagDB().outputPatched(miss);
 		listSuspects(miss);
 	}
 
@@ -749,8 +799,8 @@
 	}
 
 public:
-	ReportMaker(unsigned int itemsPerGroup = 0) :
-		voc(Debtags::Environment::get().vocabulary()),
+	ReportMaker(DebtagsSimple<Package>& debtags, unsigned int itemsPerGroup = 0) :
+		debtags(debtags),
 		itemsPerGroup(itemsPerGroup) {}
 
 	void printReport()
@@ -821,7 +871,8 @@
 }
 #endif
 
-int outputGrepped(const string& expression, bool invertMatch, TagcollConsumer<string, string>& cons)
+template<class ITEM>
+int outputGrepped(DebtagsSimple<ITEM>& debtags, const string& expression, bool invertMatch, TagcollConsumer<string, string>& cons)
 {
 	// Build the grep filter chain
 	FilterChain<string, string> filters;
@@ -835,9 +886,10 @@
 
 	filters.setConsumer(&cons);
 
-	ToStrings<Package, Tag> tostrings(Debtags::Environment::get().serializer(), &filters);
+	//ToStrings<Package, Tag> tostrings(Debtags::Environment::get().serializer(), &filters);
 
-	Debtags::Environment::get().tagDB().outputPatched(tostrings);
+	//debtags.tagDB().outputPatched(tostrings);
+	debtags.tagDB().outputPatched(filters);
 
 	return filter.countMatched() > 0 ? 0 : 1;
 }
@@ -845,13 +897,15 @@
 class MaintCollector : public PackageConsumer
 {
 protected:
+	DebtagsSimple<Package>& debtags;
 	TagcollConsumer<Maintainer, Tag>& cons;
 	
 public:
-	MaintCollector(TagcollConsumer<Maintainer, Tag>& cons) throw () : cons(cons) {}
+	MaintCollector(DebtagsSimple<Package>& debtags, TagcollConsumer<Maintainer, Tag>& cons)
+		throw () : debtags(debtags), cons(cons) {}
 	void consume(const Package& pkg) throw ()
 	{
-		cons.consume(pkg.maint(), pkg.tags());
+		cons.consume(pkg.maint(), debtags.tagDB().getTags(pkg));
 	}
 };
 
@@ -1054,8 +1108,10 @@
 		if (opts.get("debug").defined())
 			::Environment::get().debug(true);
 
-		if (cmd != UPDATE)
+		/*
+		if (cmd != UPDATE && cmd != CAT && cmd != GREP && cmd != INSTALL && cmd != TAGSHOW)
 			Debtags::Environment::init(false);
+		*/
 		
 		// Perform the correct operation
 		switch (cmd)
@@ -1063,7 +1119,18 @@
 			// Output the full package tag database
 			case CAT:
 			{
-				wantTagDatabase();
+				DebtagsSimple<string> debtags(false);
+				wantTagDatabase(debtags);
+				Tagcoll::Serializer<string, Tag> serializer(debtags.vocabulary());
+				TextFormat<string, Tag> writer(serializer, stdout);
+				if (opts.get("groupitems").defined())
+				{
+					ItemGrouper<string, Tag> grouper;
+					debtags.tagDB().outputPatched(grouper);
+					grouper.output(writer);
+				} else
+					debtags.tagDB().outputPatched(writer);
+				/*
 				TextFormat<Package, Tag> writer(Debtags::Environment::get().serializer(), stdout);
 				if (opts.get("groupitems").defined())
 				{
@@ -1072,6 +1139,7 @@
 					grouper.output(writer);
 				} else
 					Debtags::Environment::get().tagDB().outputPatched(writer);
+				*/
 
 				break;
 			}
@@ -1081,7 +1149,8 @@
 			// given tag expression
 			case GREP:
 			{
-				wantTagDatabase();
+				DebtagsSimple<string> debtags(false);
+				wantTagDatabase(debtags);
 				string expression = args.next();
 
 				Serializer<string, string> tserializer;
@@ -1090,9 +1159,9 @@
 
 				int matched;
 				if (opts.get("quiet").defined())
-					matched = outputGrepped(expression, opts.get("invert-match").defined(), sink);
+					matched = outputGrepped(debtags, expression, opts.get("invert-match").defined(), sink);
 				else
-					matched = outputGrepped(expression, opts.get("invert-match").defined(), writer);
+					matched = outputGrepped(debtags, expression, opts.get("invert-match").defined(), writer);
 
 				return matched > 0 ? 0 : 1;
 			}
@@ -1101,12 +1170,13 @@
 			// apt-get install the packages that match the given tag expression
 			case INSTALL:
 			{
-				wantTagDatabase();
+				DebtagsSimple<string> debtags(false);
+				wantTagDatabase(debtags);
 				string expression = args.next();
 
 				ItemCollector selection;
 
-				outputGrepped(expression, opts.get("invert-match").defined(), selection);
+				outputGrepped(debtags, expression, opts.get("invert-match").defined(), selection);
 
 				const char* parms[selection.size() + 1];
 				int i = 0;
@@ -1124,10 +1194,11 @@
 			// Show the vocabulary informations about a tag\n"
 			case TAGSHOW:
 			{
-				wantTagDatabase();
+				DebtagsSimple<string> debtags(false);
+				wantTagDatabase(debtags);
 				string tag = args.next();
 
-				const Debtags::Vocabulary& voc = Debtags::Environment::get().vocabulary();
+				const Debtags::Vocabulary& voc = debtags.vocabulary();
 				Tag t = voc.getTag(tag);
 				if (!t)
 				{
@@ -1144,7 +1215,8 @@
 			// Show a summary of all tags matching the given patterns
 			case TAGSEARCH:
 			{
-				wantTagDatabase();
+				DebtagsSimple<string> debtags(false);
+				wantTagDatabase(debtags);
 				// Get the patterns to be matched
 				vector<BasicTagMatcher> matchers;
 				while (args.hasNext())
@@ -1160,7 +1232,7 @@
 					return 1;
 				}
 
-				const Debtags::Vocabulary& voc = Debtags::Environment::get().vocabulary();
+				const Debtags::Vocabulary& voc = debtags.vocabulary();
 
 				FacetSet facets = voc.getFacets();
 				TagSet matches = facets.getFiltered(matchers[0]);
@@ -1177,17 +1249,16 @@
 			// Call apt-cache show <pkg>, but add tag informations to the output.\n"
 			case SHOW:
 			{
-				using namespace Debtags;
-				
-				wantTagDatabase();
+				DebtagsSimple<Package> debtags(false);
+				wantTagDatabase(debtags);
 
 				string name = args.next();
 				
-				Package pkg = Debtags::Environment::get().getPackage(name);
+				Package pkg = debtags.serializer().stringToItem(name);
 				if (pkg)
 				{
 					printf("%.*sTags: ", PFSTR(pkg.fulldata()));
-					TagSet ts = pkg.tags();
+					TagSet ts = debtags.tagDB().getTags(pkg);
 					for (TagSet::const_iterator i = ts.begin();
 							i != ts.end(); i++)
 						if (i == ts.begin())
@@ -1207,22 +1278,21 @@
 			{
 				using namespace Debtags;
 
-				wantTagDatabase();
+				DebtagsSimple<Package> debtags(false);
+				wantTagDatabase(debtags);
 
 				int maxdist = 0;
 				if (opts.get("distance").defined())
 					maxdist = opts.get("distance").intVal();
 				string pkg = args.next();
 
-				const Debtags::Environment& env = Debtags::Environment::get();
-
 				// Split the items on commas
 				string splititem;
 				PackageSet splititems;
 				for (string::const_iterator c = pkg.begin(); c != pkg.end(); c++)
 					if (*c == ',')
 					{
-						if (Package p = env.getPackage(splititem))
+						if (Package p = debtags.serializer().stringToItem(splititem))
 						{
 							splititems.insert(p);
 						} else {
@@ -1232,7 +1302,7 @@
 						splititem = string();
 					} else
 						splititem += *c;
-				if (Package p = env.getPackage(splititem))
+				if (Package p = debtags.serializer().stringToItem(splititem))
 				{
 					splititems.insert(p);
 				} else {
@@ -1242,9 +1312,9 @@
 
 				// Get the tagset as the intersection of the tagsets of all input items
 				PackageSet::const_iterator i = splititems.begin();
-				TagSet ts = (*i).tags();
+				TagSet ts = debtags.tagDB().getTags(*i);
 				for (++i; i != splititems.end(); i++)
-					ts = ts ^ (*i).tags();
+					ts = ts ^ debtags.tagDB().getTags(*i);
 
 				if (ts.empty())
 				{
@@ -1256,7 +1326,8 @@
 				}
 
 				PackagePrinter printer(splititems);
-				Debtags::Environment::get().outputRelated(printer, ts, maxdist);
+				PackageSet(debtags.tagDB().getRelatedItems(ts, maxdist)).output(printer);
+
 
 				if (printer.count() > 50 && maxdist == 0 && isatty(1))
 				{
@@ -1277,14 +1348,15 @@
 			// file is specified
 			case CHECK:
 			{
-				wantTagDatabase();
+				DebtagsSimple<string> debtags(false);
+				wantTagDatabase(debtags);
 				string file;
 				if (args.hasNext())
 					file = args.next();
 				else
 					file = Paths::path_tagdb;
 
-				const Debtags::Vocabulary& voc = Debtags::Environment::get().vocabulary();
+				const Debtags::Vocabulary& voc = debtags.vocabulary();
 
 				TagcollChecker checker(voc);
 				readCollection(file, checker);
@@ -1322,20 +1394,22 @@
 			// collection [filename]
 			case MKPATCH:
 			{
-				wantTagDatabase();
+				DebtagsSimple<string> debtags(false);
+				wantTagDatabase(debtags);
 				string file = args.next();
 
-				InputMerger<Package, Tag> merger1;
-				InputMerger<Package, Tag> merger2;
+				InputMerger<string, string> merger1;
+				InputMerger<string, string> merger2;
 
-				Debtags::Environment::get().tagDB().outputPatched(merger1);
+				debtags.tagDB().outputPatched(merger1);
 				readCollection(file, merger2);
 				//Debtags::Environment::get().tagDB().outputFile(file, merger2);
 
-				PatchList<Package, Tag> newpatches;
+				PatchList<string, string> newpatches;
 				newpatches.addPatch(merger1, merger2);
 
-				TextFormat<Package, Tag>::outputPatch(newpatches, Debtags::Environment::get().serializer(), stdout);
+				Tagcoll::Serializer<string, string> stringSer;
+				TextFormat<string, string>::outputPatch(newpatches, stringSer, stdout);
 				break;
 			}
 			// maintainers
@@ -1343,14 +1417,13 @@
 			// packages they maintain
 			case MAINTAINERS:
 			{
-				using namespace Debtags;
-
-				wantTagDatabase();
+				DebtagsSimple<Package> debtags(false);
+				wantTagDatabase(debtags);
 
 				// Gather maintainer informations
 				InputMerger<Maintainer, Tag> maints;
-				MaintCollector collector(maints);
-				Debtags::Environment::get().output(collector);
+				MaintCollector collector(debtags, maints);
+				debtags.serializer().packageDB().iterateAll(collector);
 				MaintPrinter printer;
 				maints.output(printer);
 				break;
@@ -1364,7 +1437,8 @@
 			{
 				using namespace Debtags;
 
-				wantTagDatabase();
+				DebtagsSimple<Package> debtags(false);
+				wantTagDatabase(debtags);
 
 				std::string cmd = args.next();
 
@@ -1372,7 +1446,7 @@
 				{
 					string name = args.next();
 
-					Package pkg = Debtags::Environment::get().getPackage(name);
+					Package pkg = debtags.serializer().stringToItem(name);
 					if (!pkg)
 					{
 						verbose("Package %.*s not found", PFSTR(name));
@@ -1384,7 +1458,7 @@
 					while (args.hasNext())
 					{
 						string tag = args.next();
-						Tag t = Debtags::Environment::get().vocabulary().getTag(tag);
+						Tag t = debtags.vocabulary().getTag(tag);
 						if (t)
 							tagset += t;
 						else
@@ -1398,18 +1472,18 @@
 							change.addPatch(Patch<Package, Tag>(pkg, tagset, TagSet()));
 						else
 							change.addPatch(Patch<Package, Tag>(pkg, TagSet(), tagset));
-						Debtags::Environment::get().tagDB().applyChange(change);
-						Debtags::Environment::get().tagDB().savePatch();
+						debtags.tagDB().applyChange(change);
+						debtags.tagDB().savePatch();
 					} else
 						verbose("No tags to add");
 				}
 				else if (cmd == "ls")
 				{
 					string name = args.next();
-					Package pkg = Debtags::Environment::get().getPackage(name);
+					Package pkg = debtags.serializer().stringToItem(name);
 					if (pkg)
 					{
-						TagSet ts = pkg.tags();
+						TagSet ts = debtags.tagDB().getTags(pkg);
 						for (TagSet::const_iterator i = ts.begin();
 								i != ts.end(); i++)
 							printf("%.*s\n", PFSTR(i->fullname()));
@@ -1428,17 +1502,18 @@
 			// repository
 			case SUBMIT:
 			{
-				wantTagDatabase();
+				DebtagsSimple<string> debtags(false);
+				wantTagDatabase(debtags);
 
 				if (args.hasNext())
 				{
 					StdioParserInput in(args.next());
-					PatchList<Package, Tag> patch =
-							TextFormat<Package, Tag>::parsePatch(in, Debtags::Environment::get().serializer());
-					Debtags::Environment::get().tagDB().sendPatch(patch);
+					PatchList<string, Tag> patch =
+							TextFormat<string, Tag>::parsePatch(in, debtags.serializer());
+					debtags.tagDB().sendPatch(patch);
 				}
 				else
-					Debtags::Environment::get().tagDB().sendPatch();
+					debtags.tagDB().sendPatch();
 
 				break;
 			}
@@ -1446,10 +1521,11 @@
 			// Print a list of the installed packages that are not yet tagged
 			case TODO:
 			{
-				wantTagDatabase();
+				DebtagsSimple<Package> debtags(false);
+				wantTagDatabase(debtags);
 
 				// Filter to select the right packages
-				TODOFilter filter;
+				TODOFilter filter(debtags.serializer());
 
 				// Convert tags and packages to strings
 				//ToStrings<Package, Tag> toStrings(Debtags::Environment::get().serializer());
@@ -1462,7 +1538,7 @@
 				//filter.setConsumer(&toStrings);
 				//toStrings.setConsumer(&writer);
 
-				Debtags::Environment::get().tagDB().outputPatched(filter);
+				debtags.tagDB().outputPatched(filter);
 
 				break;
 			}
@@ -1471,15 +1547,16 @@
 			// appear in the packages that are installed already
 			case SCORE:
 			{
-				wantTagDatabase();
+				DebtagsSimple<Package> debtags(false);
+				wantTagDatabase(debtags);
 
 				// Compute tag scores
 				TagsScorer tscorer;
-				Debtags::Environment::get().tagDB().outputPatched(tscorer);
+				debtags.tagDB().outputPatched(tscorer);
 
 				// Compute package scores
 				PackageScorer pscorer(tscorer);
-				Debtags::Environment::get().tagDB().outputPatched(pscorer);
+				debtags.tagDB().outputPatched(pscorer);
 
 				// Print the results
 				for (PackageScorer::const_iterator i = pscorer.begin();
@@ -1493,30 +1570,32 @@
 			// its facets only
 			case FACETCOLL:
 			{
-				wantTagDatabase();
+				DebtagsSimple<string> debtags(false);
+				wantTagDatabase(debtags);
 
-				FacetcollPrinter printer;
-				TagToFacet<Package> tagToFacet(&printer);
-				Debtags::Environment::get().tagDB().outputPatched(tagToFacet);
+				FacetcollPrinter<string> printer;
+				TagToFacet<string> tagToFacet(&printer);
+				debtags.tagDB().outputPatched(tagToFacet);
 				break;
 			}
 			// stats
 			// Print statistics about Debtags
 			case STATS:
 			{
-				wantTagDatabase();
+				DebtagsSimple<Package> debtags(false);
+				wantTagDatabase(debtags);
 
 				PackageCounter pc;
-				Debtags::Environment::get().packageDB().iterateAll(pc);
+				debtags.serializer().packageDB().iterateAll(pc);
 				printf("Total count of packages: %d\n", pc.count());
 
-				StatsCollector stats;
-				Debtags::Environment::get().tagDB().outputPatched(stats);
+				StatsCollector stats(debtags.serializer());
+				debtags.tagDB().outputPatched(stats);
 
 				printf("Total count of packages (according to APT): %d\n", pc.count());
 				printf("Total count of packages (according to Debtags): %d\n", stats.get_seen());
 
-				const Debtags::Vocabulary& voc = Debtags::Environment::get().vocabulary();
+				const Debtags::Vocabulary& voc = debtags.vocabulary();
 				printf("Number of facets: %d\n", voc.getFacets().size());
 				printf("Number of tags: %d\n", voc.getTags().size());
 
@@ -1524,7 +1603,7 @@
 				// TODO: use Debtags instead of Environment throughout all Debtags
 				TagCollection<Package, Facet> coll;
 				TagToFacet<Package> tagStripper(&coll);
-				Debtags::Environment::get().tagDB().outputPatched(tagStripper);
+				debtags.tagDB().outputPatched(tagStripper);
 				Facet f;
 				SmartHierarchyNode<Package, Facet> node(f, coll, 0);
 				printf("Number of automatically computed toplevel facets: %d\n", node.size());
@@ -1546,13 +1625,14 @@
 			// Print a report of packages needing work
 			case TODOREPORT:
 			{
-				wantTagDatabase();
+				DebtagsSimple<Package> debtags(false);
+				wantTagDatabase(debtags);
 
 				unsigned int itemsPerGroup = 0;
 				if (args.hasNext())
 					itemsPerGroup = atoi(args.next().c_str());
 
-				ReportMaker rm(itemsPerGroup);
+				ReportMaker rm(debtags, itemsPerGroup);
 				rm.printReport();
 
 				break;

Modified: debtags/trunk/src/instantiations.cc
==============================================================================
--- debtags/trunk/src/instantiations.cc	(original)
+++ debtags/trunk/src/instantiations.cc	Fri Jun 17 18:44:13 2005
@@ -4,11 +4,13 @@
 #include <debtags/Tag.h>
 
 #include <tagcoll/InputMerger.cc>
+#include <tagcoll/ItemGrouper.cc>
 #include <tagcoll/OpSet.cc>
 #include <tagcoll/TagcollConsumer.cc>
 
 // Instantiate needed templates
 
 template class InputMerger<Debtags::Maintainer, Debtags::Tag>;
+template class ItemGrouper<std::string, Debtags::Tag>;
 
 // vim:set ts=4 sw=4: