[Debtags-commits] [SCM] Command line debtags tool. branch, master, updated. 6bec300233262477fa1463a3ae0c30d18f1bdd2c
Enrico Zini
enrico at enricozini.org
Mon May 10 11:39:40 UTC 2010
The following commit has been merged in the master branch:
commit 6bec300233262477fa1463a3ae0c30d18f1bdd2c
Author: Enrico Zini <enrico at enricozini.org>
Date: Mon May 10 12:39:30 2010 +0100
Build with new libept
Build with new libept
No more debtags smartsearch, which has been obsoleted by axi-search
diff --git a/debian/changelog b/debian/changelog
index 599cbe5..db8f893 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,10 @@
+debtags (1.7.10) unstable; urgency=low
+
+ * Build with new libept
+ * No more debtags smartsearch, which has been obsoleted by axi-search
+
+ -- Enrico Zini <enrico at debian.org> Mon, 10 May 2010 12:37:33 +0100
+
debtags (1.7.9) unstable; urgency=low
* Build with new libept
diff --git a/debian/control b/debian/control
index 86bd6e2..4dd4b6f 100644
--- a/debian/control
+++ b/debian/control
@@ -3,7 +3,7 @@ Section: admin
Priority: optional
Maintainer: Enrico Zini <enrico at debian.org>
Uploaders: Arnaud Fontaine <arnaud at andesi.org>
-Build-Depends: c++abi2-dev, cdbs, debhelper (>> 4.1), dh-buildinfo, pkg-config, apt, libept-dev (>= 0.5.26), libept-dev (<< 0.6), zlib1g-dev, python-dev, python-docutils, libtagcoll2-dev (>= 2.0.4), libtagcoll2-dev (<<2.1), libwibble-dev (>= 0.1.15), libwibble-dev (<< 0.2)
+Build-Depends: c++abi2-dev, cdbs, debhelper (>> 4.1), dh-buildinfo, pkg-config, apt, libept-dev (>= 0.6.0), libept-dev (<< 0.7), zlib1g-dev, python-dev, python-docutils, libtagcoll2-dev (>= 2.0.4), libtagcoll2-dev (<<2.1), libwibble-dev (>= 0.1.15), libwibble-dev (<< 0.2)
Standards-Version: 3.8.0.0
Vcs-Svn: svn://svn.debian.org/svn/debtags/debtags/1.7
Vcs-Browser: http://svn.debian.org/wsvn/debtags/debtags/1.7
diff --git a/tools/Environment.cc b/tools/Environment.cc
index ee70354..54b94e1 100644
--- a/tools/Environment.cc
+++ b/tools/Environment.cc
@@ -21,6 +21,8 @@
#include "Environment.h"
#include <ept/apt/apt.h>
+#include <ept/debtags/debtags.h>
+#include <ept/debtags/vocabulary.h>
#include <stdio.h>
#include <stdarg.h>
@@ -42,12 +44,32 @@ Environment& Environment::get() throw ()
// Initialize the environment with default values
Environment::Environment() throw ()
- : m_apt(0), m_debtags(0), _verbose(false), _debug(false) {}
+ : m_apt(0), m_debtags(0), m_vocabulary(0), _verbose(false), _debug(false), _editable(false) {}
void Environment::init(bool editable)
{
- m_apt = new ept::apt::Apt;
- m_debtags = new ept::debtags::Debtags(editable);
+ _editable = editable;
+}
+
+/// Access the apt data provider
+ept::apt::Apt& Environment::apt()
+{
+ if (!m_apt) m_apt = new ept::apt::Apt;
+ return *m_apt;
+}
+
+/// Access the debtags data provider
+ept::debtags::Debtags& Environment::debtags()
+{
+ if (!m_debtags) m_debtags = new ept::debtags::Debtags(_editable);
+ return *m_debtags;
+}
+
+/// Access the tag vocabulary
+ept::debtags::Vocabulary& Environment::voc()
+{
+ if (!m_vocabulary) m_vocabulary = new ept::debtags::Vocabulary;
+ return *m_vocabulary;
}
void fatal_error(const char* fmt, ...) throw() ATTR_PRINTF(1, 2)
diff --git a/tools/Environment.h b/tools/Environment.h
index 7a5a5eb..801c8ba 100644
--- a/tools/Environment.h
+++ b/tools/Environment.h
@@ -21,13 +21,19 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include <ept/debtags/debtags.h>
#include <string>
namespace ept {
+
namespace apt {
class Apt;
}
+
+namespace debtags {
+class Debtags;
+class Vocabulary;
+}
+
}
class Environment
@@ -39,12 +45,18 @@ protected:
/// Debtags data provider
ept::debtags::Debtags* m_debtags;
+ /// Vocabulary data provider
+ ept::debtags::Vocabulary* m_vocabulary;
+
// True when operations should be verbose
bool _verbose;
// True when operations should be very verbose
bool _debug;
+ // Whether the debtags database is open editable
+ bool _editable;
+
Environment() throw ();
public:
@@ -58,13 +70,13 @@ public:
void init(bool editable = false);
/// Access the apt data provider
- ept::apt::Apt& apt() { return *m_apt; }
+ ept::apt::Apt& apt();
/// Access the debtags data provider
- ept::debtags::Debtags& debtags() { return *m_debtags; }
+ ept::debtags::Debtags& debtags();
/// Access the tag vocabulary
- ept::debtags::Vocabulary& voc() { return m_debtags->vocabulary(); }
+ ept::debtags::Vocabulary& voc();
// Accessor methods
diff --git a/tools/Makefile.am b/tools/Makefile.am
index 68fb8d6..4961cb7 100644
--- a/tools/Makefile.am
+++ b/tools/Makefile.am
@@ -6,10 +6,9 @@ pkgdata_SCRIPTS = fetch
debtags_SOURCES = \
Environment.cc \
- SmartSearcher.cc \
debtags.cc
debtags_LDADD = $(LIBEPT_LIBS)
INCLUDES = -I.. $(LIBEPT_CFLAGS) -DSCRIPTDIR=\"$(pkgdatadir)\"
-EXTRA_DIST = DebtagsOptions.h Environment.h Printer.h SmartSearcher.h nullstream.h fetch debtags-updatecontrol
+EXTRA_DIST = DebtagsOptions.h Environment.h Printer.h nullstream.h fetch debtags-updatecontrol
diff --git a/tools/Printer.h b/tools/Printer.h
index 6726638..e7d8e3a 100644
--- a/tools/Printer.h
+++ b/tools/Printer.h
@@ -34,6 +34,8 @@
#include <ept/apt/apt.h>
#include <ept/apt/packagerecord.h>
+#include <ept/debtags/debtags.h>
+#include <ept/debtags/vocabulary.h>
#include <ept/debtags/maint/debdbparser.h>
#if 0
#include <ept/forward.h>
@@ -57,7 +59,7 @@ public:
protected:
typedef std::string Package;
- typedef ept::debtags::Tag Tag;
+ typedef std::string Tag;
Type m_type;
int* count;
@@ -86,7 +88,7 @@ public:
std::set<std::string> facets;
for (typename TTAGS::const_iterator j = data.second.begin();
j != data.second.end(); ++j)
- facets.insert(j->facet().name());
+ facets.insert(ept::debtags::voc::getfacet(*j));
for (std::set<std::string>::const_iterator j = facets.begin();
j != facets.end(); ++j)
@@ -106,10 +108,10 @@ public:
if (j == data.second.begin())
{
std::cout << ": ";
- std::cout << j->fullname();
+ std::cout << *j;
} else {
std::cout << ", ";
- std::cout << j->fullname();
+ std::cout << *j;
}
break;
case QUIET:
@@ -131,15 +133,15 @@ public:
{
for (typename TTAGS::const_iterator i = tags.begin(); i != tags.end(); ++i)
if (i == tags.begin())
- std::cout << i->fullname();
+ std::cout << *i;
else
- std::cout << ", " + i->fullname();
+ std::cout << ", " + *i;
}
protected:
typedef std::string Package;
typedef ept::apt::Version Version;
- typedef ept::debtags::Tag Tag;
+ typedef std::string Tag;
ept::apt::Apt& apt;
ept::debtags::Debtags& debtags;
diff --git a/tools/SmartSearcher.cc b/tools/SmartSearcher.cc
deleted file mode 100644
index 64a488d..0000000
--- a/tools/SmartSearcher.cc
+++ /dev/null
@@ -1,335 +0,0 @@
-/*
- * debtags - Implement package tags support for Debian
- *
- * Copyright (C) 2003--2006 Enrico Zini <enrico at debian.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "SmartSearcher.h"
-#include "Printer.h"
-#include <ept/apt/apt.h>
-#include <ept/apt/packagerecord.h>
-#include <tagcoll/utils/set.h>
-#include <wibble/regexp.h>
-
-using namespace std;
-using namespace ept::apt;
-using namespace tagcoll;
-
-static string toLower(const std::string& s)
-{
- string res;
- for (string::const_iterator i = s.begin(); i != s.end(); ++i)
- res += tolower(*i);
- return res;
-}
-
-void SmartSearcher::splitPattern(const std::string& pattern)
-{
- patterns.clear();
-
- wibble::Tokenizer tok(pattern, "[^[:blank:]]+", REG_EXTENDED);
- for (wibble::Tokenizer::const_iterator i = tok.begin();
- i != tok.end(); ++i)
- patterns.push_back(toLower(*i));
-}
-
-bool SmartSearcher::patternMatch(const Package& pkg)
-{
- using namespace ept;
-
- std::string name = toLower(pkg);
- std::string desc;
- PackageRecord record(apt.rawRecord(pkg));
- desc = toLower(record.description());
-
- for (std::vector<std::string>::const_iterator i = patterns.begin();
- i != patterns.end(); ++i)
- if (name.find(*i) == string::npos
- && desc.find(*i) == string::npos)
- return false;
- return true;
-}
-
-bool SmartSearcher::tagMatch(const Package& pkg)
-{
- using namespace wibble::operators;
- std::set<Tag> tags = debtags.getTagsOfItem(pkg);
-
- if (!wanted.empty() && !utils::set_contains(tags, wanted))
- return false;
-
- if (!unwanted.empty() && !(tags & unwanted).empty())
- return false;
-
- return true;
-}
-
-void SmartSearcher::showSet(const std::set<Tag>& tags, const std::string& type)
-{
- for (std::set<Tag>::const_iterator i = tags.begin();
- i != tags.end(); ++i)
- {
- tagsInMenu.push_back(*i);
- cout << tagsInMenu.size() << ") " << i->fullname() << " (" << type << ")" << endl;
- }
-}
-
-void SmartSearcher::showInteresting(int max)
-{
- for (std::vector<Tag>::const_reverse_iterator i = interesting.rbegin();
- i != interesting.rend() && max > 0; ++i)
- {
- using namespace wibble::operators;
- if (utils::set_contains(wanted, *i)
- || utils::set_contains(unwanted, *i)
- || utils::set_contains(ignored, *i)
- || coll.getCardinality(*i) == 0)
- continue;
- tagsInMenu.push_back(*i);
- cout << tagsInMenu.size() << ") " << i->fullname()
- << " (" << coll.getCardinality(*i) << "/" << coll.itemCount() << ")" << endl;
- --max;
- }
-}
-
-void SmartSearcher::showDiscriminant(int max)
-{
- // Compute the most interesting tags by discriminance
- vector<Tag> discr = coll.tagsInDiscriminanceOrder();
-
- for (std::vector<Tag>::const_reverse_iterator i = discr.rbegin();
- i != discr.rend() && max > 0; ++i)
- {
- using namespace wibble::operators;
- if (utils::set_contains(wanted, *i)
- || utils::set_contains(unwanted, *i)
- || utils::set_contains(ignored, *i))
- continue;
- tagsInMenu.push_back(*i);
- cout << tagsInMenu.size() << ") " << i->fullname()
- << " (" << coll.getCardinality(*i) << "/" << coll.itemCount() << ")" << endl;
- --max;
- }
-}
-
-void SmartSearcher::showTags()
-{
- tagsInMenu.clear();
-
- showSet(wanted, "wanted");
- showSet(unwanted, "unwanted");
- showSet(ignored, "ignored");
- cout << endl;
- showInteresting();
- cout << endl;
- showDiscriminant();
-}
-
-void SmartSearcher::refilter()
-{
- // Regenerate coll
- coll = coll::Fast<Package, Tag>();
- fullColl.output(filter(inserter(coll)));
-}
-
-void SmartSearcher::computeInteresting(const std::string& pattern)
-{
- splitPattern(pattern);
-
- coll::Fast<Package, Tag> filtered;
- for (coll::Fast<Package, Tag>::const_iterator i = fullColl.begin();
- i != fullColl.end(); ++i)
- if (patternMatch(i->first))
- filtered.insert(wibble::singleton(i->first), i->second);
-
- interesting = filtered.tagsInRelevanceOrder(fullColl);
-#if 0
- // Compute the set of tags that better represent the keyword search
- TagMetrics<Tag, int> metrics1 = TagMetrics<Tag, int>::computeFromTags(fullColl);
- TagMetrics<Tag, int> metrics2 = TagMetrics<Tag, int>::computeFromTags(filtered);
-#if 0
- // Use the jump algorithm
- TagMetrics<Tag, double> jumps = metrics2.jumpsFrom(metrics1);
- interesting = jumps.tagsSortedByMetrics();
-#else
- // Use the reduction percentage algorithm (a bit faster, and more
- // optimizable)
- interesting = metrics2.tagsSortedByRelevance(metrics1);
-#endif
-#endif
-}
-
-SmartSearcher::SmartSearcher(const std::string& pattern)
- : apt(env().apt()), debtags(env().debtags())
-{
- // Perform the initial filtering using the keyword search
- Apt& apt = env().apt();
- for (Apt::iterator i = apt.begin(); i != apt.end(); ++i)
- fullColl.insert(wibble::singleton(*i), debtags.getTagsOfItem(*i));
-
- computeInteresting(pattern);
-
- coll = fullColl;
-}
-
-void SmartSearcher::interact()
-{
- bool done = false;
- while (!done)
- {
- cout << "Tag selection:" << endl;
- showTags();
- cout << coll.itemCount() << " packages selected so far." << endl;
- string ans;
- bool changed = false;
-
- // TODO: allow to add tags based on a keyword search on coll
- cout << "Your choice (+#, -#, =#, K word, View, Done, Quit, ?): ";
- if (!getline(cin, ans))
- {
- cout << endl;
- done = true;
- }
-
- while (ans != "")
- {
- // If we're setting a new keyword search, process now and skip
- // processing as a list
- if (ans[0] == '?')
- {
- cout << "+ number select the tag with the given number as a tag you want" << endl
- << "- number select the tag with the given number as a tag you do not want" << endl
- << "= number select the tag with the given number as a tag you don't care about" << endl
- << "K word recompute the set of interesting tags from a full-text search using the given word" << endl
- << "V view the packages selected so far" << endl
- << "D print the packages selected so far and exit" << endl
- << "Q quit debtags smart search" << endl
- << "? print this help information" << endl;
- ans.clear();
- }
- else if (ans[0] == 'k' || ans[0] == 'K')
- {
- // Strip initial command and empty spaces
- ans = ans.substr(1);
- while (!ans.empty() && isspace(ans[0]))
- ans = ans.substr(1);
- if (ans == "")
- cout << "The 'k' command needs a keyword to use for finding new interesting tags." << endl;
- else
- computeInteresting(ans);
- ans.clear();
- } else {
- // Split the answer by spaces
- string rest;
- size_t pos = ans.find(" ");
- if (pos != string::npos)
- {
- // Skip spaces
- for ( ; pos < ans.size() && isspace(ans[pos]); ++pos)
- ;
- rest = ans.substr(pos);
- ans = ans.substr(0, pos);
- }
- if (ans[0] == '+' || ans[0] == '-' || ans[0] == '=') {
- int idx = strtoul(ans.substr(1).c_str(), NULL, 10);
- if (idx <= 0 || (unsigned)idx > tagsInMenu.size())
- cout << "Tag " << idx << " was not on the menu." << endl;
- else
- {
- Tag tag = tagsInMenu[idx - 1];
- //cout << "Understood " << ans << " as " << ans[0] << tag.fullname() << endl;
-
- switch (ans[0])
- {
- case '+':
- wanted.insert(tag);
- unwanted.erase(tag);
- ignored.erase(tag);
- break;
- case '-':
- wanted.erase(tag);
- unwanted.insert(tag);
- ignored.erase(tag);
- break;
- case '=':
- wanted.erase(tag);
- unwanted.erase(tag);
- ignored.insert(tag);
- break;
- }
- changed = true;
- }
- } else if (ans == "V" || ans == "v") {
- coll.output(PackagePrinter(PackagePrinter::SHORT));
- } else if (ans == "D" || ans == "d") {
- coll.output(PackagePrinter(PackagePrinter::SHORT));
- done = true;
- } else if (ans == "Q" || ans == "q") {
- done = true;
- } else {
- cout << "Ignoring command \"" << ans << "\"" << endl;
- }
- ans = rest;
- }
- }
- if (changed)
- refilter();
- }
-}
-
-void SmartSearcher::outputRelevantTags()
-{
- for (std::vector<Tag>::const_iterator i = interesting.begin();
- i != interesting.end(); ++i)
- {
- using namespace wibble::operators;
- if (utils::set_contains(wanted, *i)
- || utils::set_contains(unwanted, *i)
- || utils::set_contains(ignored, *i)
- || coll.getCardinality(*i) == 0)
- continue;
- cout << i->fullname() << " - " << i->shortDescription() << endl;
- }
-}
-
-void SmartSearcher::outputDiscriminantTags()
-{
- // Compute the most interesting tags by discriminance
- coll::Fast<Package, Tag> filtered;
- for (coll::Fast<Package, Tag>::const_iterator i = fullColl.begin();
- i != fullColl.end(); ++i)
- if (patternMatch(i->first))
- filtered.insert(wibble::singleton(i->first), i->second);
-
- vector<Tag> discr = filtered.tagsInDiscriminanceOrder();
-
- for (std::vector<Tag>::const_iterator i = discr.begin();
- i != discr.end(); ++i)
- {
- using namespace wibble::operators;
- if (utils::set_contains(wanted, *i)
- || utils::set_contains(unwanted, *i)
- || utils::set_contains(ignored, *i))
- continue;
- cout << i->fullname() << " - " << i->shortDescription()
- << " (" << filtered.getDiscriminance(*i) * 200 /filtered.itemCount() << "%)" << endl;
- }
-}
-
-#include <tagcoll/coll/fast.tcc>
-
-// vim:set ts=4 sw=4:
diff --git a/tools/SmartSearcher.h b/tools/SmartSearcher.h
deleted file mode 100644
index 3f1b2a2..0000000
--- a/tools/SmartSearcher.h
+++ /dev/null
@@ -1,453 +0,0 @@
-/*
- * debtags - Implement package tags support for Debian
- *
- * Copyright (C) 2003--2006 Enrico Zini <enrico at debian.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef DEBTAGS_SMARTSEARCHER_H
-#define DEBTAGS_SMARTSEARCHER_H
-
-#include "Environment.h"
-#include <tagcoll/coll/fast.h>
-
-#include <vector>
-
-#if 0
-template<typename Tag, typename Number = int>
-class TagMetrics : public std::map<Tag, Number>
-{
- class MetricsOrder
- {
- const TagMetrics& metric;
- public:
- MetricsOrder(const TagMetrics& metric) : metric(metric) {}
- bool operator()(const Tag& t1, const Tag& t2)
- {
- // Returns true if t1 precedes t2, and false otherwise
- return metric.get(t1) < metric.get(t2);
- }
- };
- class DiscriminanceOrder
- {
- const TagMetrics& metric;
- int itemCount;
- public:
- DiscriminanceOrder(const TagMetrics& metric, int itemCount)
- : metric(metric), itemCount(itemCount) {}
- bool operator()(const Tag& t1, const Tag& t2)
- {
- // Returns true if t1 precedes t2, and false otherwise
- return metric.discriminance(t1, itemCount) < metric.discriminance(t2, itemCount);
- }
- };
- class RelevanceOrder
- {
- const TagMetrics& first;
- const TagMetrics& second;
- public:
- RelevanceOrder(const TagMetrics& first, const TagMetrics& second)
- : first(first), second(second) {}
- bool operator()(const Tag& t1, const Tag& t2)
- {
- // Replace 10000* with (double) to be formally precise but
- // use floating point aritmetics
- return 10000 * second.get(t1) / first.get(t1) < 10000 * second.get(t2) / first.get(t2);
- }
- };
-
- #if 0
- TagMetrics<Tag, double> jumpsFrom(const TagMetrics<Tag, Number>& other) const
- {
- TagMetrics<Tag, double> res;
- for (typename TagMetrics<Tag, Number>::const_iterator i = this->begin(); i != this->end(); ++i)
- {
- //cout << i->first.fullname() << " was " << other.get(i->first) << " is " << i->second << " kept " << i->second * 100 / other.get(i->first) << "%" << endl;
- res.add(i->first, (double)i->second / other.get(i->first));
- }
- return res;
- }
- #endif
-
-public:
- void add(const Tag& tag, const Number& val)
- {
- typename TagMetrics::iterator i = this->find(tag);
- if (i == this->end())
- insert(make_pair(tag, val));
- else
- i->second += val;
- }
-
- Number get(const Tag& tag) const
- {
- typename TagMetrics::const_iterator i = this->find(tag);
- if (i == this->end())
- return 0;
- else
- return i->second;
- }
-
- // Get the minimum number of packages that would be eliminated by choosing
- // this tag either as 'wanted' or as 'unwanted'
- Number discriminance(const Tag& tag, Number itemCount) const
- {
- return get(tag) < itemCount - get(tag) ? get(tag) : itemCount - get(tag);
- }
-
- TagMetrics<Tag, Number> rankMetrics() const
- {
- vector<Tag> sorted = tagsSortedByMetrics();
- TagMetrics<Tag, Number> res;
- for (size_t i = 0; i < sorted.size(); ++i)
- res.add(sorted[i], sorted.size() - i);
- return res;
- }
-
- TagMetrics<Tag, double> jumpsFrom(const TagMetrics<Tag, Number>& other) const
- {
- // Compute rank metrics
- TagMetrics<Tag, Number> rank1 = other.rankMetrics();
- TagMetrics<Tag, Number> rank2 = rankMetrics();
-
- TagMetrics<Tag, double> res;
- typename TagMetrics::const_iterator i1 = rank1.begin();
- typename TagMetrics::const_iterator i2 = rank2.begin();
- while (i1 != rank1.end() || i2 != rank2.end())
- {
- if (i1->first == i2->first)
- {
- res.add(i1->first, (i1->second - i2->second) / i2->second);
- ++i1;
- ++i2;
- } else if (i1 == rank1.end() || (i2 != rank2.end() && i2->first < i1->first)) {
- ++i2;
- } else {
- ++i1;
- }
- }
- return res;
- }
-
-
- vector<Tag> tagsSortedByMetrics() const
- {
- vector<Tag> res;
- for (typename TagMetrics::const_iterator i = this->begin(); i != this->end(); ++i)
- res.push_back(i->first);
- std::sort(res.begin(), res.end(), MetricsOrder(*this));
- return res;
- }
-
- vector<Tag> tagsSortedByDiscriminance(int itemCount) const
- {
- vector<Tag> res;
- for (typename TagMetrics::const_iterator i = this->begin(); i != this->end(); ++i)
- res.push_back(i->first);
- std::sort(res.begin(), res.end(), DiscriminanceOrder(*this, itemCount));
- return res;
- }
-
- vector<Tag> tagsSortedByRelevance(const TagMetrics<Tag, Number>& other)
- {
- vector<Tag> res;
- for (typename TagMetrics::const_iterator i = this->begin(); i != this->end(); ++i)
- res.push_back(i->first);
- std::sort(res.begin(), res.end(), RelevanceOrder(other, *this));
- return res;
- }
-
- template<typename COLL>
- static TagMetrics<Tag, Number> computeFromTags(const COLL& coll)
- {
- TagMetrics<Tag, Number> res;
- for (typename COLL::const_tag_iterator i = coll.tagBegin();
- i != coll.tagEnd(); ++i)
- res.add(i->first, i->second.size());
- return res;
- }
-
- void dump(const std::string& prefix, ostream& out)
- {
- TagMetrics<Tag, Number> rm = rankMetrics();
- vector<Tag> tags = tagsSortedByMetrics();
- int rank = 0;
- for (typename vector<Tag>::const_iterator i = tags.begin(); i != tags.end(); ++i, ++rank)
- out << prefix << tags.size() - rank << ":" << rm.get(*i) << ") " << i->fullname() << ": " << this->get(*i) << std::endl;
- }
-};
-
-template<typename Metrics>
-class TagMetricsInserter : public wibble::mixin::OutputIterator< TagMetricsInserter<Metrics> >
-{
- Metrics& m;
-
-public:
- TagMetricsInserter(Metrics& m) : m(m) {}
-
- template<typename Items, typename Tags>
- TagMetricsInserter<Metrics>& operator=(const std::pair<Items, Tags>& data)
- {
- int size = data.first.size();
- for (typename Tags::const_iterator i = data.second.begin();
- i != data.second.end(); ++i)
- m.add(*i, size);
- return *this;
- }
-};
-
-template<typename Tag, typename Number>
-TagMetricsInserter< TagMetrics<Tag, Number> > tagMetricsInserter(TagMetrics<Tag, Number>& out)
-{
- return TagMetricsInserter< TagMetrics<Tag, Number> >(out);
-}
-#endif
-
-
-class SmartSearcher
-{
-protected:
- typedef std::string Package;
- typedef ept::debtags::Tag Tag;
-
- ept::apt::Apt& apt;
- ept::debtags::Debtags& debtags;
-
- // TODO:
- // 1) funzione di ranking dei tag che calcola, sul subset indotto da
- // {wanted, unwanted}, la rilevanza dei tag dopo il filtraggio con la
- // keyword
- // 2) iterare usando la nuova funzione di ranking
- tagcoll::coll::Fast<Package, Tag> fullColl;
- tagcoll::coll::Fast<Package, Tag> coll;
-
- std::vector<std::string> patterns;
- std::set<Tag> wanted;
- std::set<Tag> unwanted;
- std::set<Tag> ignored;
- std::vector<Tag> interesting;
-
- std::vector<Tag> tagsInMenu;
-
- void splitPattern(const std::string& pattern);
- bool patternMatch(const Package& pkg);
- bool tagMatch(const Package& pkg);
-
- template<typename OUT>
- class Filter : public wibble::mixin::OutputIterator< Filter<OUT> >
- {
- SmartSearcher& s;
- OUT out;
-
- public:
- Filter(SmartSearcher& s, const OUT& out) : s(s), out(out) {}
-
- template<typename ITEMS, typename TAGS>
- Filter<OUT>& operator=(const std::pair<ITEMS, TAGS>& data)
- {
- for (typename ITEMS::const_iterator i = data.first.begin();
- i != data.first.end(); ++i)
- {
- if (!s.tagMatch(*i))
- continue;
-#if 0
- bool matches = s.patternMatch(*i);
- for (typename TAGS::const_iterator t = data.second.begin();
- t != data.second.end(); ++t)
- {
- r.incFull(*t);
- ++r.totalFull;
- if (matches)
- {
- r.incFilt(*t);
- ++r.totalFilt;
- }
- }
-#endif
- *out = data;
- ++out;
- }
- return *this;
- }
- };
- template<typename OUT>
- Filter<OUT> filter(const OUT& out)
- {
- return Filter<OUT>(*this, out);
- }
-
- #if 0
- void autoSelect(const std::vector<Tag>& tags, size_t maxAuto = 5, size_t maxUser = 7)
- {
- interesting.clear();
- if (tags.empty())
- return;
-
- size_t autoCount = (tags.size() - maxUser) / 2;
- if (autoCount > maxAuto) autoCount = maxAuto;
- size_t userCount = tags.size() - (2 * autoCount);
- if (userCount > maxUser) userCount = maxUser;
-
- // Use the bottom autoCount tags as unwanted
- for (size_t i = 0; i < autoCount; ++i)
- unwanted.insert(tags[i]);
-
- // Use the top autoCount tags as wanted
- for (size_t i = tags.size() - 1; i >= tags.size() - autoCount; --i)
- wanted.insert(tags[i]);
-
- // Get the next userCount packages as interesting
- for (size_t i = tags.size() - autoCount - 1; i >= tags.size() - autoCount - userCount; --i)
- interesting.push_back(tags[i]);
- }
- #endif
-
- void showSet(const std::set<Tag>& tags, const std::string& type);
- void showInteresting(int max = 7);
- void showDiscriminant(int max = 7);
- void showTags();
- void refilter();
- void computeInteresting(const std::string& pattern);
-
-public:
- SmartSearcher(const std::string& pattern);
-
- void interact();
- void outputRelevantTags();
- void outputDiscriminantTags();
-
-
-#if 0
- component::PackageTags& debtags;
- Printer<Package, Tag>* printer;
- map<Tag, size_t> tagCount;
- OpSet<Tag> m_topTags;
-
- virtual void consumeItemUntagged(const Package& pkg)
- {
- printer->consume(pkg);
- CardinalityStore<Package, Tag>::consumeItemUntagged(pkg);
- }
- virtual void consumeItem(const Package& pkg, const Tagcoll::OpSet<Tag>& tags)
- {
- printer->consume(pkg, tags);
- CardinalityStore<Package, Tag>::consumeItem(pkg, tags);
- for (OpSet<Tag>::const_iterator i = tags.begin();
- i != tags.end(); i++)
- ++tagCount[*i];
- }
- virtual void consumeItemsUntagged(const Tagcoll::OpSet<Package>& pkgs)
- {
- printer->consume(pkgs);
- CardinalityStore<Package, Tag>::consumeItemsUntagged(pkgs);
- }
- virtual void consumeItems(const Tagcoll::OpSet<Package>& pkgs, const Tagcoll::OpSet<Tag>& tags)
- {
- printer->consume(pkgs, tags);
- CardinalityStore<Package, Tag>::consumeItems(pkgs, tags);
- for (OpSet<Tag>::const_iterator i = tags.begin();
- i != tags.end(); i++)
- tagCount[*i] += pkgs.size();
- }
-
- vector< pair<Tag, size_t> > getTopTags(size_t count)
- {
- vector< pair<Tag, size_t> > res;
- for (map<Tag, size_t>::const_iterator i = tagCount.begin();
- i != tagCount.end(); i++)
- {
- pair<Tag, size_t> hand = *i;
- for (size_t j = 0; j < count; j++)
- {
- if (j >= res.size())
- {
- res.push_back(hand);
- break;
- }
- else if (hand.second > res[j].second)
- {
- pair<Tag, size_t> tmp = res[j];
- res[j] = hand;
- hand = tmp;
- }
- }
- }
- return res;
- }
-
-public:
- SmartSearcher(component::PackageTags& debtags, Printer<Package, Tag>* printer) :
- debtags(debtags), printer(printer) {}
-
- void clear()
- {
- CardinalityStore<Package, Tag>::operator=(CardinalityStore<Package, Tag>());
- tagCount.clear();
- m_topTags.clear();
- }
-
- OpSet<Tag> topTags() { return m_topTags; }
-
- int outputRelated()
- {
- const size_t relevantTags = 5;
- vector< pair<Tag, size_t> > topTagList = getTopTags(relevantTags);
- Scores<Tag> scores;
- vector< OpSet<Tag> > tagsets;
- float distance = relevantTags;
- int count = 0;
-
- m_topTags.clear();
- for (vector< pair<Tag, size_t> >::const_iterator i = topTagList.begin();
- i != topTagList.end(); i++)
- m_topTags += i->first;
-
- // Get the tagsets that score less in weighted distance from topTags
- for (tagsets_t::const_iterator i = this->tagsets.begin();
- i != this->tagsets.end(); i++)
- {
- float d = scores.distance(m_topTags, i->first);
- if (d <= distance)
- {
- if (d < distance)
- {
- tagsets.clear();
- distance = d;
- }
- tagsets.push_back(i->first);
- }
- }
-
- // print the items they have
- for (vector< OpSet<Tag> >::const_iterator i = tagsets.begin();
- i != tagsets.end(); i++)
- {
- OpSet<Package> pkgs = debtags.tagdb().getItems(*i);
- printer->consume(pkgs, *i);
- count += pkgs.size();
- }
- return count;
- }
-
- virtual void flush()
- {
- printer->flush();
- }
-#endif
-};
-
-#endif
-// vim:set ts=4 sw=4:
diff --git a/tools/debtags.cc b/tools/debtags.cc
index 7ab1c4d..4ec2ea0 100644
--- a/tools/debtags.cc
+++ b/tools/debtags.cc
@@ -34,19 +34,17 @@
#include <tagcoll/SmartHierarchy.h>
#include <tagcoll/coll/simple.h>
#include <tagcoll/utils/set.h>
+#include <tagcoll/patch.h>
#include "Environment.h"
#include "DebtagsOptions.h"
#include "Printer.h"
#include "nullstream.h"
-#include "SmartSearcher.h"
#include <ept/apt/packagerecord.h>
-#include <ept/debtags/expression.h>
-#include <ept/debtags/maint/vocabularymerger.h>
+#include <ept/debtags/debtags.h>
+#include <ept/debtags/vocabulary.h>
#include <ept/debtags/maint/path.h>
-#include <ept/debtags/maint/vocabularyindexer.h>
-#include <ept/debtags/maint/debtagsindexer.h>
#include <wibble/sys/fs.h>
@@ -107,11 +105,7 @@ public:
template<typename ITEMS, typename TAGS>
ExpressionFilter<OUT>& operator=(const std::pair<ITEMS, TAGS>& data)
{
- std::set<std::string> tags;
- for (typename TAGS::const_iterator i = data.second.begin();
- i != data.second.end(); ++i)
- tags.insert(i->fullname());
- bool matched = expr(tags);
+ bool matched = expr(data.second);
if (invert)
matched = !matched;
if (matched)
@@ -151,12 +145,12 @@ protected:
public:
void add(const std::string& pattern) { patterns.push_back(pattern); }
- bool operator()(const Facet& item)
+ bool operator()(const voc::Data& item)
{
for (vector<string>::const_iterator i = patterns.begin();
i != patterns.end(); i++)
{
- if (strcasestr(item.name().c_str(), i->c_str()))
+ if (strcasestr(item.name.c_str(), i->c_str()))
return true;
if (strcasestr(item.shortDescription().c_str(), i->c_str()))
return true;
@@ -165,22 +159,6 @@ public:
}
return false;
}
- bool operator()(const Tag& item)
- {
- //cerr << "Testing: " << item.fullname() << endl;
- for (vector<string>::const_iterator i = patterns.begin();
- i != patterns.end(); i++)
- {
- if (strcasestr(item.fullname().c_str(), i->c_str()))
- return true;
- if (strcasestr(item.shortDescription().c_str(), i->c_str()))
- return true;
- if (strcasestr(item.longDescription().c_str(), i->c_str()))
- return true;
- }
- //cerr << " not passed." << endl;
- return false;
- }
};
template<class OUT>
@@ -231,13 +209,7 @@ public:
PackageState s = env().apt().state(*i);
if (!(s.isInstalled() || s.upgradable() || s.nowBroken()))
continue;
- std::set<string> tags;
- for (typename TAGS::const_iterator j = data.second.begin();
- j != data.second.end(); ++j)
- {
- tags.insert(j->fullname());
- }
- if (nyt(tags))
+ if (nyt(data.second))
{
*out = make_pair(wibble::singleton(*i), data.second);
++out;
@@ -286,15 +258,10 @@ public:
if (data.second.empty())
++stats.notags;
else {
- std::set<string> tags;
- for (typename TAGS::const_iterator i = data.second.begin();
- i != data.second.end(); ++i)
- tags.insert(i->fullname());
-
- if (has_nyt(tags)) {
+ if (has_nyt(data.second)) {
++stats.nyt;
++stats.onlynyt;
- for (set<string>::const_iterator i = tags.begin(); i != tags.end(); ++i)
+ for (set<string>::const_iterator i = data.second.begin(); i != data.second.end(); ++i)
if (i->substr(0, 23) != "special::not-yet-tagged")
{
--stats.onlynyt;
@@ -302,7 +269,7 @@ public:
}
} else {
++stats.tagged;
- if (is_ct(tags))
+ if (is_ct(data.second))
++stats.complete;
}
}
@@ -406,29 +373,29 @@ VocabularyFilter<VOC, OUT> vocabularyFilter(const VOC& voc, const OUT& out)
return VocabularyFilter<VOC, OUT>(voc, out);
}
-static void printShortVocabularyItem(const Facet& facet)
+static void printShortVocabularyItem(const voc::FacetData& facet)
{
- cout << facet.name() << " (facet) - " << facet.shortDescription() << endl;
+ cout << facet.name << " (facet) - " << facet.shortDescription() << endl;
}
-static void printShortVocabularyItem(const Tag& tag)
+static void printShortVocabularyItem(const voc::TagData& tag)
{
- cout << tag.fullname() << " - " << tag.shortDescription() << endl;
+ cout << tag.name << " - " << tag.shortDescription() << endl;
}
-static void printVocabularyItem(const Facet& tag)
+static void printVocabularyItem(const voc::FacetData& tag)
{
string ld = tag.longDescription();
- cout << "Facet: " << tag.name() << endl;
+ cout << "Facet: " << tag.name << endl;
cout << "Description: " << tag.shortDescription() << endl;
cout << " " << ld << endl;
if (ld[ld.size() - 1] != '\n')
cout << endl;
}
-static void printVocabularyItem(const Tag& tag)
+static void printVocabularyItem(const voc::TagData& tag)
{
string ld = tag.longDescription();
- cout << "Tag: " << tag.fullname() << endl;
+ cout << "Tag: " << tag.name << endl;
cout << "Description: " << tag.shortDescription() << endl;
cout << " " << ld << endl;
if (ld[ld.size() - 1] != '\n')
@@ -459,8 +426,8 @@ public:
}
for (typename TAGS::const_iterator i = data.second.begin();
i != data.second.end(); ++i)
- if (i->valid())
- tags.insert(i->fullname());
+ if (env().voc().hasTag(*i))
+ tags.insert(*i);
if (!items.empty())
{
*out = make_pair(items, tags);
@@ -479,7 +446,7 @@ PackageToMaint<OUT> packageToMaint(const OUT& out)
struct PackageScore
{
// tag -> (installed, total)
- map<Tag, pair<int, int> > tagScore;
+ map<std::string, pair<int, int> > tagScore;
set<string> uninstalled;
void output(Debtags& debtags, ostream& out)
@@ -490,13 +457,13 @@ struct PackageScore
i != uninstalled.end(); ++i)
{
// Compute package score
- set<Tag> tags = debtags.getTagsOfItem(*i);
+ set<std::string> tags = debtags.getTagsOfItem(*i);
int score = 0;
int ntags = 0;
- for (set<Tag>::const_iterator t = tags.begin();
+ for (set<std::string>::const_iterator t = tags.begin();
t != tags.end(); ++t)
{
- map<Tag, pair<int, int> >::const_iterator j = tagScore.find(*t);
+ map<std::string, pair<int, int> >::const_iterator j = tagScore.find(*t);
if (j != tagScore.end())
{
score += 100 * j->second.first / j->second.second;
@@ -556,12 +523,12 @@ public:
for (typename TAGS::const_iterator t = data.second.begin();
t != data.second.end(); ++t)
{
- std::set<Tag> it;
+ std::set<std::string> it;
it.insert(*t);
if (!avoidTag(it))
{
//cerr << "Count " << t->fullname() << endl;
- map<Tag, pair<int, int> >::iterator j = res.tagScore.find(*t);
+ map<std::string, pair<int, int> >::iterator j = res.tagScore.find(*t);
if (j == res.tagScore.end())
res.tagScore.insert(make_pair(*t, make_pair(installed ? 1 : 0, 1)));
else
@@ -577,13 +544,6 @@ public:
}
};
-struct PackageToString {
- string operator()(const string& pkg) { return pkg; }
-} serPackage;
-struct TagToString {
- string operator()(const Tag& tag) { return tag.fullname(); }
-} serTag;
-
int main(int argc, const char* argv[])
{
wibble::commandline::DebtagsOptions opts;
@@ -608,25 +568,21 @@ int main(int argc, const char* argv[])
Apt& apt = env().apt();
// ensure that all facets are readable
- std::set<Facet> facets = voc.facets();
- for (std::set<Facet>::const_iterator i = facets.begin(); i != facets.end(); i++)
+ std::set<std::string> facets = voc.facets();
+ for (std::set<std::string>::const_iterator i = facets.begin(); i != facets.end(); i++)
{
- cout << "Checking facet " << i->name(string("<invalid name>")) << "..." << endl;
- i->name(string("foo"));
- i->shortDescription(string("foo"));
- i->longDescription(string("foo"));
- i->tags();
+ cout << "Checking facet " << *i << "..." << endl;
+ if (voc.facetData(*i) == 0)
+ cerr << "No data for facet " << *i << endl;
}
// ensure that all tags are readable
- std::set<Tag> tags = voc.tags();
- for (std::set<Tag>::const_iterator i = tags.begin(); i != tags.end(); i++)
+ std::set<std::string> tags = voc.tags();
+ for (std::set<std::string>::const_iterator i = tags.begin(); i != tags.end(); i++)
{
- cout << "Checking tag " << i->fullname(string("<invalid name>")) << "..." << endl;
- i->name(string("foo"));
- i->fullname(string("foo"));
- i->shortDescription(string("foo"));
- i->longDescription(string("foo"));
+ cout << "Checking tag " << *i << "..." << endl;
+ if (voc.tagData(*i) == 0)
+ cerr << "No data for tag " << *i << endl;
}
// ensure that all packages that declare they are readable, are readable
@@ -641,17 +597,25 @@ int main(int argc, const char* argv[])
//}
}
- for (std::set<Facet>::const_iterator i = facets.begin();
+ for (std::set<std::string>::const_iterator i = facets.begin();
i != facets.end(); i++)
{
- if (!voc.hasFacet(i->name()))
- cerr << "Vocabulary is not sure about having facet " << i->name() << endl;
-
- std::set<Tag> tags = i->tags();
- for (std::set<Tag>::const_iterator j = tags.begin();
+ if (!voc.hasFacet(*i))
+ cerr << "Vocabulary is not sure about having facet " << *i << endl;
+ const voc::FacetData* f = voc.facetData(*i);
+ if (!f)
+ cerr << "Vocabulary is really not sure about having facet " << *i << endl;
+
+ std::set<std::string> tags = f->tags();
+ for (std::set<std::string>::const_iterator j = tags.begin();
j != tags.end(); j++)
- if (!voc.hasTag(j->fullname()))
- cerr << "Vocabulary is not sure about having tag " << j->fullname() << endl;
+ {
+ if (!voc.hasTag(*j))
+ cerr << "Vocabulary is not sure about having tag " << *j << endl;
+ const voc::TagData* t = voc.tagData(*j);
+ if (!t)
+ cerr << "Vocabulary is really not sure about having tag " << *j << endl;
+ }
}
return 0;
}
@@ -777,16 +741,22 @@ int main(int argc, const char* argv[])
env().init();
Vocabulary& voc = env().voc();
- std::set<Facet> facets = voc.facets();
- for (std::set<Facet>::const_iterator i = facets.begin();
+ std::set<std::string> facets = voc.facets();
+ for (std::set<std::string>::const_iterator i = facets.begin();
i != facets.end(); i++)
{
- printVocabularyItem(*i);
+ const voc::FacetData* f = voc.facetData(*i);
+ if (!f) continue;
+ printVocabularyItem(*f);
- std::set<Tag> tags = i->tags();
- for (std::set<Tag>::const_iterator j = tags.begin();
+ std::set<std::string> tags = f->tags();
+ for (std::set<std::string>::const_iterator j = tags.begin();
j != tags.end(); j++)
- printVocabularyItem(*j);
+ {
+ const voc::TagData* t = voc.tagData(*i);
+ if (!t) continue;
+ printVocabularyItem(*t);
+ }
}
return 0;
}
@@ -797,15 +767,15 @@ int main(int argc, const char* argv[])
env().init();
string tag = opts.next();
- Tag t = env().voc().tagByName(tag);
- if (!t.valid())
+ const voc::TagData* t = env().voc().tagData(tag);
+ if (!t)
{
verbose("Tag `%s' was not found in tag vocabulary\n", tag.c_str());
return 1;
}
else
{
- printVocabularyItem(t);
+ printVocabularyItem(*t);
return 0;
}
}
@@ -833,24 +803,30 @@ int main(int argc, const char* argv[])
int matched = 0;
- std::set<Facet> facets = env().voc().facets();
- for (std::set<Facet>::const_iterator i = facets.begin();
+ std::set<std::string> facets = env().voc().facets();
+ for (std::set<std::string>::const_iterator i = facets.begin();
i != facets.end(); i++)
{
- if (match(*i))
+ const voc::FacetData* f = env().voc().facetData(*i);
+ if (!f) continue;
+ if (match(*f))
{
matched++;
- printShortVocabularyItem(*i);
+ printShortVocabularyItem(*f);
}
- std::set<Tag> tags = i->tags();
- for (std::set<Tag>::const_iterator j = tags.begin();
+ std::set<std::string> tags = f->tags();
+ for (std::set<std::string>::const_iterator j = tags.begin();
j != tags.end(); j++)
- if (match(*j))
+ {
+ const voc::TagData* t = env().voc().tagData(*j);
+ if (!t) continue;
+ if (match(*t))
{
matched++;
- printShortVocabularyItem(*j);
+ printShortVocabularyItem(*t);
}
+ }
}
return matched > 0 ? 0 : 1;
@@ -912,8 +888,8 @@ int main(int argc, const char* argv[])
}
// Get the tagset as the intersection of the tagsets of all input items
- std::set<string>::const_iterator i = splititems.begin();
- std::set<Tag> ts = env().debtags().getTagsOfItem(*i);
+ std::set<std::string>::const_iterator i = splititems.begin();
+ std::set<std::string> ts = env().debtags().getTagsOfItem(*i);
for (++i; i != splititems.end(); i++)
ts &= env().debtags().getTagsOfItem(*i);
@@ -950,12 +926,12 @@ int main(int argc, const char* argv[])
if (count > 50 && maxdist == 0 && isatty(1))
{
string tags;
- for (std::set<Tag>::const_iterator i = ts.begin();
+ for (std::set<std::string>::const_iterator i = ts.begin();
i != ts.end(); i++)
if (i == ts.begin())
- tags += i->fullname();
+ tags += *i;
else
- tags += "%2C" + i->fullname();
+ tags += "%2C" + *i;
feedback("\nIt seems that this set of packages lacks tag information that could help to better distinguish package similarities.\nYou can help providing better tagging: just point your browser to http://debian.vitavonni.de/packagebrowser/?tags=%s\n", tags.c_str());
}
return 0;
@@ -993,24 +969,23 @@ int main(int argc, const char* argv[])
return 1;
}
- std::set<Tag> tagset;
+ std::set<std::string> tagset;
while (opts.hasNext())
{
string tag = opts.next();
- Tag t = env().voc().tagByName(tag);
- if (t)
- tagset.insert(t);
+ if (env().voc().hasTag(tag))
+ tagset.insert(tag);
else
error("Tag '%s' not found: ignored\n", tag.c_str());
}
if (!tagset.empty())
{
- PatchList<string, Tag> change;
+ PatchList<string, std::string> change;
if (cmd == "add")
- change.addPatch(Patch<string, Tag>(pkg, tagset, std::set<Tag>()));
+ change.addPatch(Patch<string, std::string>(pkg, tagset, std::set<std::string>()));
else
- change.addPatch(Patch<string, Tag>(pkg, std::set<Tag>(), tagset));
+ change.addPatch(Patch<string, std::string>(pkg, std::set<std::string>(), tagset));
env().debtags().applyChange(change);
env().debtags().savePatch();
} else
@@ -1022,10 +997,10 @@ int main(int argc, const char* argv[])
string pkg = opts.next();
if (env().apt().isValid(pkg))
{
- std::set<Tag> ts = env().debtags().getTagsOfItem(pkg);
- for (std::set<Tag>::const_iterator i = ts.begin();
+ std::set<std::string> ts = env().debtags().getTagsOfItem(pkg);
+ for (std::set<std::string>::const_iterator i = ts.begin();
i != ts.end(); i++)
- cout << i->fullname() << endl;
+ cout << *i << endl;
return 0;
} else {
verbose("Package %s not found", pkg.c_str());
@@ -1156,38 +1131,13 @@ int main(int argc, const char* argv[])
env().init();
string file = opts.next();
- coll::Simple<string, Tag> coll;
+ coll::Simple<string, std::string> coll;
env().debtags().outputSystem(file, inserter(coll));
- PatchList<string, Tag> newpatches;
+ PatchList<string, std::string> newpatches;
newpatches.addPatch(env().debtags(), coll);
- textformat::outputPatch(serPackage, serTag, newpatches, stdout);
- }
- // ssearch <word [word1 [word2 ...]]>
- // Perform a keyword search integrated with related packages
- else if (opts.foundCommand() == opts.smartsearch)
- {
- env().init();
- if (!opts.hasNext())
- throw wibble::exception::BadOption("you should specify one pattern to search");
-
- string keywords;
- while (opts.hasNext())
- if (keywords.empty())
- keywords = opts.next();
- else
- keywords += " " + opts.next();
-
- SmartSearcher searcher(keywords);
-
- if (opts.smse_reltags->boolValue())
- searcher.outputRelevantTags();
- else if (opts.smse_disctags->boolValue())
- searcher.outputDiscriminantTags();
- else {
- searcher.interact();
- }
+ textformat::outputPatch(newpatches, stdout);
}
// update
// Updates the package tag database (requires root)
@@ -1214,24 +1164,14 @@ int main(int argc, const char* argv[])
}
}
+ // Skip env, so we don't load the tag database if we
+ // don't need it
- // Access the indexes to trigger a rebuild
- //typedef ept::t::cache::debtags::IndexManager<> IndexManager;
- std::string a, b;
-
- //auto_ptr<Ept> ept = debtagsInit();
- env().init();
-
- VocabularyIndexer::obtainWorkingVocabulary(a, b);
- verbose("Vocabulary: %s\n", a.c_str());
- verbose("Vocabulary index: %s\n", b.c_str());
-
- DebtagsIndexer::obtainWorkingDebtags(env().voc(), a, b);
- verbose("Tag database: %s\n", a.c_str());
- verbose("Tag database index: %s\n", b.c_str());
+ // Read new vocabulary data
+ Vocabulary voc;
- //mode_t prev_umask = umask(022);
- //umask(prev_umask);
+ // Write out the merged, updated vocabulary
+ voc.write();
}
else if (opts.foundCommand() == opts.vocfilter)
{
@@ -1243,7 +1183,7 @@ int main(int argc, const char* argv[])
if (opts.misc_vocfile->boolValue())
{
- VocabularyMerger vm;
+ Vocabulary vm(true);
input::Stdio input(opts.misc_vocfile->stringValue());
vm.read(input);
readCollection(file, vocabularyFilter(vm, textformat::OstreamWriter(cout)));
--
Command line debtags tool.
More information about the Debtags-commits
mailing list