aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Piotr Jaroszyński <peper@gentoo.org> 2007-08-10 21:27:50 +0000
committerAvatar Piotr Jaroszyński <peper@gentoo.org> 2007-08-10 21:27:50 +0000
commitb2a5edd145d8678e5bc5f6ac1270a9b296f09b40 (patch)
treec3d35475ecfa5809e0eb256d733c3558baff7e18
parentcd2522d4e1c624d4b0ce1e0bf936e46559f273fd (diff)
downloadpaludis-b2a5edd145d8678e5bc5f6ac1270a9b296f09b40.tar.gz
paludis-b2a5edd145d8678e5bc5f6ac1270a9b296f09b40.tar.xz
Group QA messages. Fixes: ticket:338
-rw-r--r--paludis/files.m42
-rw-r--r--paludis/qa.cc1
-rw-r--r--paludis/qa.hh11
-rw-r--r--paludis/qa.sr14
-rw-r--r--paludis/repositories/e/qa/eapi_supported.cc2
-rw-r--r--paludis/repositories/e/qa/homepage_key.cc11
-rw-r--r--paludis/repositories/e/qa/qa_controller.cc56
-rw-r--r--paludis/repositories/e/qa/short_description_key.cc13
-rw-r--r--paludis/repositories/e/qa/spec_keys.cc20
-rw-r--r--paludis/repositories/e/qa/spec_keys_TEST.cc2
-rw-r--r--paludis/repositories/e/qa/stray_files.cc2
-rw-r--r--python/qa.cc24
-rwxr-xr-xpython/qa_TEST.py20
-rwxr-xr-xpython/repository_TEST.py2
-rw-r--r--ruby/paludis_ruby.cc9
-rw-r--r--ruby/paludis_ruby.hh5
-rw-r--r--ruby/qa.cc149
-rw-r--r--ruby/qa_TEST.rb43
-rw-r--r--ruby/repository_TEST.rb2
-rw-r--r--src/clients/qualudis/qualudis.cc8
20 files changed, 336 insertions, 60 deletions
diff --git a/paludis/files.m4 b/paludis/files.m4
index de9f20a..01cee1b 100644
--- a/paludis/files.m4
+++ b/paludis/files.m4
@@ -30,7 +30,7 @@ add(`name', `hh', `cc', `fwd', `test', `sr', `se')
add(`package_database', `hh', `cc', `test', `se')
add(`package_id', `hh', `cc', `fwd', `se')
add(`paludis', `hh')
-add(`qa', `hh', `cc', `fwd', `se')
+add(`qa', `hh', `cc', `fwd', `se', `sr')
add(`query', `hh', `cc')
add(`repository', `hh', `fwd', `cc', `sr')
add(`repository_info', `hh', `fwd', `cc')
diff --git a/paludis/qa.cc b/paludis/qa.cc
index fe60f14..d3b8cfc 100644
--- a/paludis/qa.cc
+++ b/paludis/qa.cc
@@ -25,6 +25,7 @@
using namespace paludis;
#include <paludis/qa-se.cc>
+#include <paludis/qa-sr.cc>
QAReporter::~QAReporter()
{
diff --git a/paludis/qa.hh b/paludis/qa.hh
index a1dbeb8..1483a3b 100644
--- a/paludis/qa.hh
+++ b/paludis/qa.hh
@@ -21,20 +21,19 @@
#define PALUDIS_GUARD_PALUDIS_QA_HH 1
#include <paludis/qa-fwd.hh>
-#include <paludis/util/fs_entry-fwd.hh>
+#include <paludis/util/fs_entry.hh>
+#include <paludis/util/sr.hh>
namespace paludis
{
+#include <paludis/qa-sr.hh>
+
class PALUDIS_VISIBLE QAReporter
{
public:
virtual ~QAReporter() = 0;
- virtual void message(
- const FSEntry & what,
- const QAMessageLevel,
- const std::string & name,
- const std::string & message) = 0;
+ virtual void message(const QAMessage &) = 0;
};
}
diff --git a/paludis/qa.sr b/paludis/qa.sr
new file mode 100644
index 0000000..97634f5
--- /dev/null
+++ b/paludis/qa.sr
@@ -0,0 +1,14 @@
+#!/bin/bash
+# vim: set sw=4 sts=4 et :
+
+make_class_QAMessage()
+{
+ visible
+
+ key entry "FSEntry"
+ key level "QAMessageLevel"
+ key name "std::string"
+ key message "std::string"
+
+ allow_named_args
+}
diff --git a/paludis/repositories/e/qa/eapi_supported.cc b/paludis/repositories/e/qa/eapi_supported.cc
index 902b9d2..fea8eb4 100644
--- a/paludis/repositories/e/qa/eapi_supported.cc
+++ b/paludis/repositories/e/qa/eapi_supported.cc
@@ -35,7 +35,7 @@ paludis::erepository::eapi_supported_check(
if (! id->eapi()->supported)
{
- reporter.message(entry, qaml_severe, name, "EAPI '" + stringify(id->eapi()->name) + "' not supported");
+ reporter.message(QAMessage(entry, qaml_severe, name, "EAPI '" + stringify(id->eapi()->name) + "' not supported"));
return false;
}
diff --git a/paludis/repositories/e/qa/homepage_key.cc b/paludis/repositories/e/qa/homepage_key.cc
index eb89765..3c66d45 100644
--- a/paludis/repositories/e/qa/homepage_key.cc
+++ b/paludis/repositories/e/qa/homepage_key.cc
@@ -62,7 +62,7 @@ namespace
~HomepageChecker()
{
if (! found_one)
- reporter.message(entry, qaml_normal, name, "Homepage specifies no URIs");
+ reporter.message(QAMessage(entry, qaml_normal, name, "Homepage specifies no URIs"));
}
void visit_leaf(const URIDepSpec & u)
@@ -70,17 +70,18 @@ namespace
found_one = true;
if (! u.renamed_url_suffix().empty())
- reporter.message(entry, qaml_normal, name, "Homepage uses -> in part '" + u.text() + "'");
+ reporter.message(
+ QAMessage(entry, qaml_normal, name, "Homepage uses -> in part '" + u.text() + "'"));
if (0 == u.original_url().compare(0, 7, "http://") &&
0 == u.original_url().compare(0, 8, "https://") &&
0 == u.original_url().compare(0, 6, "ftp://"))
- reporter.message(entry, qaml_normal, name, "Homepage uses no or unknown protocol in part '" + u.text() + "'");
+ reporter.message(QAMessage(entry, qaml_normal, name, "Homepage uses no or unknown protocol in part '" + u.text() + "'"));
}
void visit_leaf(const LabelsDepSpec<URILabelVisitorTypes> &)
{
- reporter.message(entry, qaml_normal, name, "Homepage uses labels");
+ reporter.message(QAMessage(entry, qaml_normal, name, "Homepage uses labels"));
}
};
}
@@ -95,7 +96,7 @@ paludis::erepository::homepage_key_check(
Context context("When performing check '" + name + "' using homepage_key_check on ID '" + stringify(*id) + "':");
if (! id->homepage_key())
- reporter.message(entry, qaml_normal, name, "No homepage available");
+ reporter.message(QAMessage(entry, qaml_normal, name, "No homepage available"));
else
{
HomepageChecker h(entry, reporter, id, name);
diff --git a/paludis/repositories/e/qa/qa_controller.cc b/paludis/repositories/e/qa/qa_controller.cc
index 9504614..d7c7918 100644
--- a/paludis/repositories/e/qa/qa_controller.cc
+++ b/paludis/repositories/e/qa/qa_controller.cc
@@ -33,6 +33,7 @@
#include <algorithm>
#include <list>
+#include <map>
using namespace paludis;
using namespace paludis::erepository;
@@ -45,15 +46,45 @@ namespace
QAReporter & base;
Mutex mutex;
+ std::multimap<const FSEntry, const QAMessage> message_buf;
+ typedef std::multimap<const FSEntry, const QAMessage>::iterator MessageIterator;
+
ThreadSafeQAReporter(QAReporter & b) :
base(b)
{
}
- void message(const FSEntry & f, QAMessageLevel l, const std::string & s, const std::string & t)
+ ~ThreadSafeQAReporter()
+ {
+ if (! std::uncaught_exception())
+ {
+ using namespace tr1::placeholders;
+ std::for_each(message_buf.begin(), message_buf.end(),
+ tr1::bind(&QAReporter::message, tr1::ref(base),
+ tr1::bind<const QAMessage>(&std::pair<const FSEntry, const QAMessage>::second, _1)));
+ }
+ }
+
+ void flush(const FSEntry & f)
+ {
+ Lock lock(mutex);
+
+ std::string root(stringify(f));
+
+ for (MessageIterator i(message_buf.lower_bound(f)), i_end(message_buf.end()) ; i != i_end ; )
+ {
+ if (0 != stringify(i->first).compare(0, root.length(), root))
+ break;
+
+ base.message(i->second);
+ message_buf.erase(i++);
+ }
+ }
+
+ void message(const QAMessage & msg)
{
Lock lock(mutex);
- base.message(f, l, s, t);
+ message_buf.insert(std::make_pair(msg.entry, msg));
}
};
}
@@ -123,10 +154,13 @@ QAController::_run_category(const CategoryNamePart & c)
}
catch (const Exception & e)
{
- _imp->reporter.message(_imp->repo->layout()->category_directory(c), qaml_severe, "category_dir_checks_group",
- "Caught exception '" + e.message() + "' (" + e.what() + ")");
+ _imp->reporter.message(
+ QAMessage(_imp->repo->layout()->category_directory(c), qaml_severe, "category_dir_checks_group",
+ "Caught exception '" + e.message() + "' (" + e.what() + ")"));
}
+ _imp->reporter.flush(_imp->repo->layout()->category_directory(c));
+
tr1::shared_ptr<const QualifiedPackageNameSet> packages(_imp->repo->package_names(c));
parallel_for_each(packages->begin(), packages->end(), tr1::bind(&QAController::_run_package, this, _1));
}
@@ -137,6 +171,8 @@ QAController::_run_package(const QualifiedPackageName & p)
using namespace tr1::placeholders;
tr1::shared_ptr<const PackageIDSequence> ids(_imp->repo->package_ids(p));
parallel_for_each(ids->begin(), ids->end(), tr1::bind(&QAController::_run_id, this, _1));
+
+ _imp->reporter.flush(_imp->repo->layout()->package_directory(p));
}
void
@@ -155,8 +191,9 @@ QAController::_run_id(const tr1::shared_ptr<const PackageID> & i)
}
catch (const Exception & e)
{
- _imp->reporter.message(_imp->repo->layout()->package_file(*i), qaml_severe, "package_id_checks_group",
- "Caught exception '" + e.message() + "' (" + e.what() + ")");
+ _imp->reporter.message(
+ QAMessage(_imp->repo->layout()->package_file(*i), qaml_severe, "package_id_checks_group",
+ "Caught exception '" + e.message() + "' (" + e.what() + ")"));
}
}
@@ -177,10 +214,13 @@ QAController::run()
}
catch (const Exception & e)
{
- _imp->reporter.message(_imp->repo->params().location, qaml_severe, "tree_checks_group",
- "Caught exception '" + e.message() + "' (" + e.what() + ")");
+ _imp->reporter.message(
+ QAMessage(_imp->repo->params().location, qaml_severe, "tree_checks_group",
+ "Caught exception '" + e.message() + "' (" + e.what() + ")"));
}
+ _imp->reporter.flush(_imp->repo->params().location);
+
tr1::shared_ptr<const CategoryNamePartSet> categories(_imp->repo->category_names());
parallel_for_each(categories->begin(), categories->end(), tr1::bind(&QAController::_run_category, this, _1));
}
diff --git a/paludis/repositories/e/qa/short_description_key.cc b/paludis/repositories/e/qa/short_description_key.cc
index 131819a..b493162 100644
--- a/paludis/repositories/e/qa/short_description_key.cc
+++ b/paludis/repositories/e/qa/short_description_key.cc
@@ -33,18 +33,19 @@ paludis::erepository::short_description_key_check(
Context context("When performing check '" + name + "' using short_description_key_check on ID '" + stringify(*id) + "':");
if (! id->short_description_key())
- reporter.message(entry, qaml_normal, name, "No description available");
+ reporter.message(QAMessage(entry, qaml_normal, name, "No description available"));
else if (id->short_description_key()->value() == stringify(id->name()))
- reporter.message(entry, qaml_normal, name, "Description is equal to PN");
+ reporter.message(QAMessage(entry, qaml_normal, name, "Description is equal to PN"));
else if (std::string::npos != id->short_description_key()->value().find("Based on the")
&& std::string::npos != id->short_description_key()->value().find("eclass"))
- reporter.message(entry, qaml_normal, name, "Description is about as useful as a chocolate teapot");
+ reporter.message(
+ QAMessage(entry, qaml_normal, name, "Description is about as useful as a chocolate teapot"));
else if (id->short_description_key()->value().length() < 10)
- reporter.message(entry, qaml_normal, name, "Description is suspiciously short");
+ reporter.message(QAMessage(entry, qaml_normal, name, "Description is suspiciously short"));
else if (id->short_description_key()->value().length() > 300)
- reporter.message(entry, qaml_normal, name, "Description written by Duncan?");
+ reporter.message(QAMessage(entry, qaml_normal, name, "Description written by Duncan?"));
else if (id->short_description_key()->value().length() > 120)
- reporter.message(entry, qaml_normal, name, "Description is too long");
+ reporter.message(QAMessage(entry, qaml_normal, name, "Description is too long"));
return true;
}
diff --git a/paludis/repositories/e/qa/spec_keys.cc b/paludis/repositories/e/qa/spec_keys.cc
index 8eb9976..53dbe82 100644
--- a/paludis/repositories/e/qa/spec_keys.cc
+++ b/paludis/repositories/e/qa/spec_keys.cc
@@ -71,8 +71,8 @@ namespace
void visit_leaf(const BlockDepSpec & b)
{
if (child_of_any)
- reporter.message(entry, qaml_normal, name, "'|| ( )' block with block child '!"
- + stringify(*b.blocked_spec()) + "' in spec key '" + stringify(key.raw_name()) + "'");
+ reporter.message(QAMessage(entry, qaml_normal, name, "'|| ( )' block with block child '!"
+ + stringify(*b.blocked_spec()) + "' in spec key '" + stringify(key.raw_name()) + "'"));
}
void visit_leaf(const URIDepSpec &)
@@ -92,12 +92,15 @@ namespace
GenericSpecTree::ConstSequenceIterator end)
{
if (child_of_any)
- reporter.message(entry, qaml_normal, name, "'|| ( )' block with 'use? ( )' child in spec key '" + stringify(key.raw_name()) + "'");
+ reporter.message(QAMessage(entry, qaml_normal, name,
+ "'|| ( )' block with 'use? ( )' child in spec key '"
+ + stringify(key.raw_name()) + "'"));
Save<unsigned> save_level(&level, level + 1);
Save<bool> save_child_of_any(&child_of_any, false);
if (cur == end)
- reporter.message(entry, qaml_normal, name, "Empty 'use? ( )' block in spec key '" + stringify(key.raw_name()) + "'");
+ reporter.message(QAMessage(entry, qaml_normal, name,
+ "Empty 'use? ( )' block in spec key '" + stringify(key.raw_name()) + "'"));
else
std::for_each(cur, end, accept_visitor(*this));
}
@@ -111,7 +114,8 @@ namespace
if (cur == end)
{
if (level > 1)
- reporter.message(entry, qaml_normal, name, "Empty '( )' block in spec key '" + stringify(key.raw_name()) + "'");
+ reporter.message(QAMessage(entry, qaml_normal, name,
+ "Empty '( )' block in spec key '" + stringify(key.raw_name()) + "'"));
}
else
std::for_each(cur, end, accept_visitor(*this));
@@ -124,11 +128,13 @@ namespace
Save<unsigned> save_level(&level, level + 1);
Save<bool> save_child_of_any(&child_of_any, true);
if (cur == end)
- reporter.message(entry, qaml_normal, name, "Empty '|| ( )' block in spec key '" + stringify(key.raw_name()) + "'");
+ reporter.message(QAMessage(entry, qaml_normal, name,
+ "Empty '|| ( )' block in spec key '" + stringify(key.raw_name()) + "'"));
else if (next(cur) == end)
{
cur->accept(*this);
- reporter.message(entry, qaml_normal, name, "'|| ( )' block with only one child in spec key '" + stringify(key.raw_name()) + "'");
+ reporter.message(QAMessage(entry, qaml_normal, name,
+ "'|| ( )' block with only one child in spec key '" + stringify(key.raw_name()) + "'"));
}
else
std::for_each(cur, end, accept_visitor(*this));
diff --git a/paludis/repositories/e/qa/spec_keys_TEST.cc b/paludis/repositories/e/qa/spec_keys_TEST.cc
index 2ec05a0..f3d502e 100644
--- a/paludis/repositories/e/qa/spec_keys_TEST.cc
+++ b/paludis/repositories/e/qa/spec_keys_TEST.cc
@@ -42,7 +42,7 @@ namespace
{
}
- void message(const FSEntry &, QAMessageLevel, const std::string &, const std::string &)
+ void message(const QAMessage &)
{
++count;
}
diff --git a/paludis/repositories/e/qa/stray_files.cc b/paludis/repositories/e/qa/stray_files.cc
index 155edc3..08b882c 100644
--- a/paludis/repositories/e/qa/stray_files.cc
+++ b/paludis/repositories/e/qa/stray_files.cc
@@ -41,7 +41,7 @@ paludis::erepository::stray_files_check(
if (dir.exists())
for (DirIterator d(dir), d_end ; d != d_end ; ++d)
if (stray(repo, *d))
- reporter.message(*d, qaml_normal, name, "Stray file");
+ reporter.message(QAMessage(*d, qaml_normal, name, "Stray file"));
return true;
}
diff --git a/python/qa.cc b/python/qa.cc
index e48040f..75ba272 100644
--- a/python/qa.cc
+++ b/python/qa.cc
@@ -31,10 +31,10 @@ struct QAReporterWrapper :
QAReporter,
bp::wrapper<QAReporter>
{
- void message(const FSEntry & f, QAMessageLevel qml, const std::string & s, const std::string & m)
+ void message(const QAMessage & msg)
{
if (get_override("message"))
- get_override("message")(f, qml, s, m);
+ get_override("message")(msg);
else
throw PythonMethodNotImplemented("QAReporter", "message");
}
@@ -57,6 +57,24 @@ void PALUDIS_VISIBLE expose_qa()
"NEED_DOC");
/**
+ * QAMessage
+ */
+ bp::class_<QAMessage>
+ (
+ "QAMessage",
+ "NEED_DOC",
+ bp::init<const FSEntry &, const QAMessageLevel, const std::string &, const std::string &>()
+ )
+ .add_property("entry", bp::make_getter(&QAMessage::entry, bp::return_value_policy<bp::return_by_value>()))
+
+ .def_readonly("level", &QAMessage::level)
+
+ .def_readonly("name", &QAMessage::name)
+
+ .def_readonly("message", &QAMessage::message)
+ ;
+
+ /**
* QAReporter
*/
bp::class_<QAReporterWrapper, boost::noncopyable>
@@ -66,7 +84,7 @@ void PALUDIS_VISIBLE expose_qa()
bp::init<>()
)
.def("message", bp::pure_virtual(&QAReporter::message),
- "message(QAMessageLevel, str, str)\n"
+ "message(QAMessage)\n"
"NEED_DOC"
)
;
diff --git a/python/qa_TEST.py b/python/qa_TEST.py
index e486518..f710bc0 100755
--- a/python/qa_TEST.py
+++ b/python/qa_TEST.py
@@ -21,7 +21,7 @@
from paludis import *
import unittest
-class TestCase_QACheckProperties(unittest.TestCase):
+class TestCase_01_QACheckProperties(unittest.TestCase):
def test_01_create(self):
QACheckProperties()
@@ -35,14 +35,26 @@ class TestCase_QACheckProperties(unittest.TestCase):
qcp += QACheckProperty.NEEDS_NETWORK
self.assert_(qcp[QACheckProperty.NEEDS_NETWORK])
-class TestCase_QAReporter(unittest.TestCase):
+class TestCase_02_QAMessage(unittest.TestCase):
+ def test_01_create(self):
+ qm = QAMessage("entry", QAMessageLevel.DEBUG, "name", "message")
+
+ def test_02_data_members(self):
+ qm = QAMessage("entry", QAMessageLevel.DEBUG, "name", "message")
+
+ self.assertEquals(qm.entry, "entry")
+ self.assertEquals(qm.level, QAMessageLevel.DEBUG)
+ self.assertEquals(qm.name, "name")
+ self.assertEquals(qm.message, "message")
+
+class TestCase_03_QAReporter(unittest.TestCase):
import paludis
if hasattr(paludis, "QAReporter"):
class PyQAR(QAReporter):
def __init__(self):
QAReporter.__init__(self)
- def message(self, l, s, m):
+ def message(self, msg):
return 1
def test_01_create(self):
@@ -55,7 +67,7 @@ class TestCase_QAReporter(unittest.TestCase):
self.assert_(isinstance(self.PyQAR(), QAReporter))
def test_04_subclass_message(self):
- self.assertEquals(self.PyQAR().message(QAMessageLevel.DEBUG, "foo", "foo"), 1)
+ self.assertEquals(self.PyQAR().message(QAMessage("foo", QAMessageLevel.DEBUG, "foo", "foo")), 1)
if __name__ == "__main__":
diff --git a/python/repository_TEST.py b/python/repository_TEST.py
index 9caaf04..f223db7 100755
--- a/python/repository_TEST.py
+++ b/python/repository_TEST.py
@@ -211,7 +211,7 @@ class TestCase_02_RepositoryInterfaces(unittest.TestCase):
QAReporter.__init__(self)
self.messages = 0
- def message(self, f, l, s, m):
+ def message(self, msg):
self.messages += 1
qi = repo.qa_interface
diff --git a/ruby/paludis_ruby.cc b/ruby/paludis_ruby.cc
index 52882dd..1a8e77f 100644
--- a/ruby/paludis_ruby.cc
+++ b/ruby/paludis_ruby.cc
@@ -316,16 +316,13 @@ paludis::ruby::RubyQAReporter::RubyQAReporter(VALUE* ruby_reporter) {
}
void
-paludis::ruby::RubyQAReporter::message(const FSEntry & f, const QAMessageLevel l, const std::string & s, const std::string & m)
+paludis::ruby::RubyQAReporter::message(const QAMessage & msg)
{
try
{
ID message_id = rb_intern("message");
- VALUE f_val = rb_str_new2(stringify(f).c_str());
- VALUE l_val = INT2FIX(l);
- VALUE s_val = rb_str_new2(s.c_str());
- VALUE m_val = rb_str_new2(m.c_str());
- rb_funcall(*(this->reporter), message_id, 4, f_val, l_val, s_val, m_val);
+ VALUE msg_val = qa_message_to_value(msg);
+ rb_funcall(*(this->reporter), message_id, 1, msg_val);
}
catch (const std::exception & e)
{
diff --git a/ruby/paludis_ruby.hh b/ruby/paludis_ruby.hh
index 186a516..0644123 100644
--- a/ruby/paludis_ruby.hh
+++ b/ruby/paludis_ruby.hh
@@ -56,7 +56,7 @@ namespace paludis
public:
RubyQAReporter(VALUE*);
- void message(const FSEntry &, const QAMessageLevel, const std::string &, const std::string &);
+ void message(const QAMessage &);
};
#endif
@@ -85,6 +85,9 @@ namespace paludis
VALUE qualified_package_name_to_value(const QualifiedPackageName &);
VALUE contents_to_value(tr1::shared_ptr<const Contents>);
VALUE repository_mask_info_to_value(tr1::shared_ptr<const RepositoryMaskInfo>);
+#ifdef ENABLE_RUBY_QA
+ VALUE qa_message_to_value(const QAMessage &);
+#endif
VersionSpec value_to_version_spec(VALUE v);
tr1::shared_ptr<const PackageID> value_to_package_id(VALUE);
diff --git a/ruby/qa.cc b/ruby/qa.cc
index 2501da8..924d7f6 100644
--- a/ruby/qa.cc
+++ b/ruby/qa.cc
@@ -32,6 +32,7 @@ namespace
static VALUE c_qa_message_level;
static VALUE c_qa_check_property;
static VALUE c_qa_check_properties;
+ static VALUE c_qa_message;
static VALUE c_qa_reporter;
VALUE
@@ -118,16 +119,127 @@ namespace
/*
* call-seq:
- * message(fs_entry, qa_message_level, source, message)
+ * message(qa_message)
*
* Process a qa error message
*/
VALUE
- ruby_qa_reporter_message(VALUE, VALUE, VALUE, VALUE)
+ ruby_qa_reporter_message(VALUE)
{
return Qnil;
}
+ VALUE
+ qa_message_init(int, VALUE *, VALUE self)
+ {
+ return self;
+ }
+
+ /*
+ * call-seq:
+ * QAMessage.new(fs_entry_string, qa_message_level, name_string, message_string) -> QAMessage
+ *
+ * Creates a new QAMessage.
+ */
+ VALUE
+ qa_message_new(int argc, VALUE *argv, VALUE self)
+ {
+ QAMessage * ptr(0);
+ try
+ {
+ if (4 == argc)
+ {
+ int ml = NUM2INT(argv[1]);
+ if (ml < 0 || ml >= last_qaml)
+ rb_raise(rb_eArgError, "QAMessageLevel out of range");
+
+ ptr = new QAMessage(FSEntry(StringValuePtr(argv[0])), static_cast<QAMessageLevel>(ml),
+ StringValuePtr(argv[2]), StringValuePtr(argv[3]));
+ }
+ else
+ {
+ rb_raise(rb_eArgError, "QAMessage expects four arguments, but got %d", argc);
+ }
+
+ VALUE tdata(Data_Wrap_Struct(self, 0, &Common<QAMessage>::free, ptr));
+ rb_obj_call_init(tdata, argc, argv);
+ return tdata;
+ }
+ catch (const std::exception & e)
+ {
+ delete ptr;
+ exception_to_ruby_exception(e);
+ }
+ }
+
+
+ /*
+ * call-seq:
+ * level -> QAMessageLevel
+ *
+ * Fetch QAMessage level.
+ */
+ VALUE
+ qa_message_level(VALUE self)
+ {
+ QAMessage * m_ptr;
+ Data_Get_Struct(self, QAMessage, m_ptr);
+ return INT2FIX(m_ptr->level);
+ }
+
+ /*
+ * call-seq:
+ * level=
+ *
+ * Set QAMessage level.
+ */
+ VALUE
+ qa_message_level_set(VALUE self, VALUE qa_message_level)
+ {
+ QAMessage * m_ptr;
+ Data_Get_Struct(self, QAMessage, m_ptr);
+ try
+ {
+ int ml = NUM2INT(qa_message_level);
+ if (ml < 0 || ml >= last_qaml)
+ rb_raise(rb_eArgError, "QAMessageLevel out of range");
+ m_ptr->level = static_cast<QAMessageLevel>(ml);
+ return Qnil;
+ }
+ catch (const std::exception & e)
+ {
+ exception_to_ruby_exception(e);
+ }
+ }
+
+ template <typename T_, typename M_, M_ T_::*m_>
+ struct FetchSetString
+ {
+ static VALUE
+ fetch(VALUE self)
+ {
+ T_ * p;
+ Data_Get_Struct(self, T_, p);
+ return rb_str_new2(stringify(p->*m_).c_str());
+ }
+
+ static VALUE
+ set(VALUE self, VALUE str)
+ {
+ try
+ {
+ T_ * p;
+ Data_Get_Struct(self, T_, p);
+ p->*m_ = M_ ((StringValuePtr(str)));
+ return Qnil;
+ }
+ catch (const std::exception & e)
+ {
+ exception_to_ruby_exception(e);
+ }
+ }
+ };
+
void do_register_qa()
{
/*
@@ -136,7 +248,7 @@ namespace
* Base class for QAReporter, create a new sublclass that implements a message function.
*/
c_qa_reporter = rb_define_class_under(paludis_module(), "QAReporter", rb_cObject);
- rb_define_method(c_qa_reporter, "message", RUBY_FUNC_CAST(&ruby_qa_reporter_message), 4);
+ rb_define_method(c_qa_reporter, "message", RUBY_FUNC_CAST(&ruby_qa_reporter_message), 1);
/*
* Document-class: Paludis::QACheckProperties
@@ -176,7 +288,29 @@ namespace
l = static_cast<QACheckProperty>(static_cast<int>(l) + 1))
rb_define_const(c_qa_check_property, value_case_to_RubyCase(stringify(l)).c_str(), INT2FIX(l));
-
+ /*
+ * Document-class: Paludis::QAMessage
+ *
+ * QA message.
+ *
+ */
+ c_qa_message = rb_define_class_under(paludis_module(), "QAMessage", rb_cObject);
+ rb_define_singleton_method(c_qa_message, "new", RUBY_FUNC_CAST(&qa_message_new), -1);
+ rb_define_method(c_qa_message, "initialize", RUBY_FUNC_CAST(&qa_message_init), -1);
+ rb_define_method(c_qa_message, "entry",
+ RUBY_FUNC_CAST((&FetchSetString<QAMessage, FSEntry, &QAMessage::entry>::fetch)), 0);
+ rb_define_method(c_qa_message, "entry=",
+ RUBY_FUNC_CAST((&FetchSetString<QAMessage, FSEntry, &QAMessage::entry>::set)), 1);
+ rb_define_method(c_qa_message, "level", RUBY_FUNC_CAST(&qa_message_level), 0);
+ rb_define_method(c_qa_message, "level=", RUBY_FUNC_CAST(&qa_message_level_set), 1);
+ rb_define_method(c_qa_message, "name",
+ RUBY_FUNC_CAST((&FetchSetString<QAMessage, std::string, &QAMessage::name>::fetch)), 0);
+ rb_define_method(c_qa_message, "name=",
+ RUBY_FUNC_CAST((&FetchSetString<QAMessage, std::string, &QAMessage::name>::set)), 1);
+ rb_define_method(c_qa_message, "message",
+ RUBY_FUNC_CAST((&FetchSetString<QAMessage, std::string, &QAMessage::message>::fetch)), 0);
+ rb_define_method(c_qa_message, "message=",
+ RUBY_FUNC_CAST((&FetchSetString<QAMessage, std::string, &QAMessage::message>::set)), 1);
}
}
@@ -197,3 +331,10 @@ paludis::ruby::value_to_qa_check_properties(VALUE v)
rb_raise(rb_eTypeError, "Can't convert %s into QACheckProperties", rb_obj_classname(v));
}
}
+
+VALUE
+paludis::ruby::qa_message_to_value(const QAMessage & qamsg)
+{
+ QAMessage * qamsg2(new QAMessage(qamsg));
+ return Data_Wrap_Struct(c_qa_message, 0, &Common<QAMessage>::free, qamsg2);
+}
diff --git a/ruby/qa_TEST.rb b/ruby/qa_TEST.rb
index 6b18ce5..7cff390 100644
--- a/ruby/qa_TEST.rb
+++ b/ruby/qa_TEST.rb
@@ -55,5 +55,48 @@ module Paludis
assert_respond_to QAReporter.new, :message
end
end
+
+ class TestCase_QAMessage < Test::Unit::TestCase
+ def qm
+ unless @qm
+ @qm = QAMessage.new('/entry', QAMessageLevel::Debug, 'name', 'message')
+ end
+ @qm
+ end
+
+ def test_create
+ qm
+ end
+
+ def test_respond
+ assert_respond_to qm, :entry
+ assert_respond_to qm, :entry=
+ assert_respond_to qm, :level
+ assert_respond_to qm, :level=
+ assert_respond_to qm, :name
+ assert_respond_to qm, :name=
+ assert_respond_to qm, :message
+ assert_respond_to qm, :message=
+ end
+
+ def test_data_members
+ assert_equal '/entry', qm.entry
+ qm.entry = '/new_entry'
+ assert_equal '/new_entry', qm.entry
+
+ assert_equal QAMessageLevel::Debug, qm.level
+ qm.level = QAMessageLevel::Maybe
+ assert_equal QAMessageLevel::Maybe, qm.level
+
+ assert_equal 'name', qm.name
+ qm.name = 'new_name'
+ assert_equal 'new_name', qm.name
+
+ assert_equal 'message', qm.message
+ qm.message = 'new_message'
+ assert_equal 'new_message', qm.message
+ end
+
+ end
end
diff --git a/ruby/repository_TEST.rb b/ruby/repository_TEST.rb
index 70c9369..0b9d186 100644
--- a/ruby/repository_TEST.rb
+++ b/ruby/repository_TEST.rb
@@ -201,7 +201,7 @@ module Paludis
class TestQAReporter < QAReporter
@messages
- def message(f, l, s, m)
+ def message(qa_msg)
@messages+=1
end
diff --git a/src/clients/qualudis/qualudis.cc b/src/clients/qualudis/qualudis.cc
index 97e5a32..87b8f22 100644
--- a/src/clients/qualudis/qualudis.cc
+++ b/src/clients/qualudis/qualudis.cc
@@ -57,11 +57,11 @@ namespace
struct QualudisReporter :
QAReporter
{
- void message(const FSEntry & f, const QAMessageLevel l, const std::string & s, const std::string & m)
+ void message(const QAMessage & msg)
{
- std::cout << colour(cl_package_name, strip_leading_string(stringify(f.strip_leading(FSEntry::cwd())), "/"))
- << ": " << s << " [" << colour(cl_error, l) << "] "
- << std::endl << " " << m << std::endl;
+ std::cout << colour(cl_package_name, strip_leading_string(stringify(msg.entry.strip_leading(FSEntry::cwd())), "/"))
+ << ": " << msg.name << " [" << colour(cl_error, msg.level) << "] "
+ << std::endl << " " << msg.message << std::endl;
}
};
}