aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2006-02-08 22:51:51 +0000
committerAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2006-02-08 22:51:51 +0000
commit19585d0f50885e1ad22001ce16dd9d8ea06840f7 (patch)
tree967df10bf41ca8e1dfc6a78251cb86c3a0c351c9
parent04bcb7ce514cb5967ae4062519e5007497fee251 (diff)
downloadpaludis-19585d0f50885e1ad22001ce16dd9d8ea06840f7.tar.gz
paludis-19585d0f50885e1ad22001ce16dd9d8ea06840f7.tar.xz
Unify qualudis message reporting.
-rw-r--r--src/qualudis/Makefile.am1
-rw-r--r--src/qualudis/check_deps_exist.cc120
-rw-r--r--src/qualudis/check_self_deps.cc122
-rw-r--r--src/qualudis/qa_notice.cc74
-rw-r--r--src/qualudis/qa_notice.hh91
-rw-r--r--src/qualudis/qualudis.cc109
6 files changed, 376 insertions, 141 deletions
diff --git a/src/qualudis/Makefile.am b/src/qualudis/Makefile.am
index 54f50ed..bfbf52c 100644
--- a/src/qualudis/Makefile.am
+++ b/src/qualudis/Makefile.am
@@ -9,6 +9,7 @@ bin_PROGRAMS = qualudis
qualudis_SOURCES = \
check_deps_exist.hh check_deps_exist.cc \
check_self_deps.hh check_self_deps.cc \
+ qa_notice.hh qa_notice.cc \
qualudis_command_line.hh qualudis_command_line.cc \
qualudis.cc
diff --git a/src/qualudis/check_deps_exist.cc b/src/qualudis/check_deps_exist.cc
index 5812a6b..5547631 100644
--- a/src/qualudis/check_deps_exist.cc
+++ b/src/qualudis/check_deps_exist.cc
@@ -18,61 +18,79 @@
*/
#include <paludis/paludis.hh>
-#include <iostream>
#include <algorithm>
#include <list>
#include "check_deps_exist.hh"
+#include "qa_notice.hh"
using namespace paludis;
-using std::cout;
-using std::cerr;
-using std::endl;
-struct DepExistsChecker :
- DepAtomVisitorTypes::ConstVisitor
+class DepExistsChecker :
+ public DepAtomVisitorTypes::ConstVisitor
{
- const Environment * const env;
- std::list<std::string> bad_deps;
- bool in_block;
+ private:
+ const Environment * const _env;
+ std::list<std::string> _bad_deps;
+ bool _in_block;
+ QANoticeLevel _level;
+
+ public:
+ const std::list<std::string> & bad_deps;
+ const QANoticeLevel & level;
+
+ DepExistsChecker(const Environment * const e) :
+ _env(e),
+ _in_block(false),
+ _level(qal_info),
+ bad_deps(_bad_deps),
+ level(_level)
+ {
+ }
- DepExistsChecker(const Environment * const e) :
- env(e),
- in_block(false)
- {
- }
+ void visit(const AllDepAtom * a)
+ {
+ std::for_each(a->begin(), a->end(), accept_visitor(this));
+ }
- void visit(const AllDepAtom * a)
- {
- std::for_each(a->begin(), a->end(), accept_visitor(this));
- }
+ void visit(const AnyDepAtom * a)
+ {
+ std::for_each(a->begin(), a->end(), accept_visitor(this));
+ }
- void visit(const AnyDepAtom * a)
- {
- std::for_each(a->begin(), a->end(), accept_visitor(this));
- }
+ void visit(const UseDepAtom * a)
+ {
+ std::for_each(a->begin(), a->end(), accept_visitor(this));
+ }
- void visit(const UseDepAtom * a)
- {
- std::for_each(a->begin(), a->end(), accept_visitor(this));
- }
+ void visit(const BlockDepAtom * a)
+ {
+ Save<bool> save_in_block(&_in_block, true);
+ a->blocked_atom()->accept(this);
+ }
- void visit(const BlockDepAtom * a)
- {
- Save<bool> save_in_block(&in_block, true);
- a->blocked_atom()->accept(this);
- }
+ void visit(const PackageDepAtom * a)
+ {
+ if (_env->package_database()->query(a)->empty())
+ {
+ if (_in_block)
+ {
+ _bad_deps.push_back("!" + stringify(*a));
+ _level = std::max(_level, qal_maybe);
+ }
+ else
+ {
+ _bad_deps.push_back(stringify(*a));
+ _level = std::max(_level, qal_major);
+ }
+ }
+ }
- void visit(const PackageDepAtom * a)
- {
- if (env->package_database()->query(a)->empty())
+ void clear()
{
- if (in_block)
- bad_deps.push_back("!" + stringify(*a));
- else
- bad_deps.push_back(stringify(*a));
+ _bad_deps.clear();
+ _level = qal_info;
}
- }
};
int
@@ -85,30 +103,30 @@ check_deps_exist(const Environment * const env, const PackageDatabaseEntry & e)
DepParser::parse(metadata->get(vmk_depend))->accept(&checker);
if (! checker.bad_deps.empty())
{
- cout << "[WARNING] In DEPEND for '" << e << "', these entries do not "
- "exist: '" << join(checker.bad_deps.begin(), checker.bad_deps.end(),
- "', '") << "'" << endl;
- checker.bad_deps.clear();
+ *QANotices::get_instance() << QANotice(checker.level, stringify(e),
+ "Nonexistent DEPEND entries: " + join(checker.bad_deps.begin(),
+ checker.bad_deps.end(), "', '") + "'");
+ checker.clear();
ret_code |= 1;
}
DepParser::parse(metadata->get(vmk_rdepend))->accept(&checker);
if (! checker.bad_deps.empty())
{
- cout << "[WARNING] In RDEPEND for '" << e << "', these entries do not "
- "exist: '" << join(checker.bad_deps.begin(), checker.bad_deps.end(),
- "', '") << "'" << endl;
- checker.bad_deps.clear();
+ *QANotices::get_instance() << QANotice(checker.level, stringify(e),
+ "Nonexistent RDEPEND entries: " + join(checker.bad_deps.begin(),
+ checker.bad_deps.end(), "', '") + "'");
+ checker.clear();
ret_code |= 1;
}
DepParser::parse(metadata->get(vmk_pdepend))->accept(&checker);
if (! checker.bad_deps.empty())
{
- cout << "[WARNING] In PDEPEND for '" << e << "', these entries do not "
- "exist: '" << join(checker.bad_deps.begin(), checker.bad_deps.end(),
- "', '") << "'" << endl;
- checker.bad_deps.clear();
+ *QANotices::get_instance() << QANotice(checker.level, stringify(e),
+ "Nonexistent PDEPEND entries: " + join(checker.bad_deps.begin(),
+ checker.bad_deps.end(), "', '") + "'");
+ checker.clear();
ret_code |= 1;
}
diff --git a/src/qualudis/check_self_deps.cc b/src/qualudis/check_self_deps.cc
index 13a0159..2456875 100644
--- a/src/qualudis/check_self_deps.cc
+++ b/src/qualudis/check_self_deps.cc
@@ -18,63 +18,80 @@
*/
#include <paludis/paludis.hh>
-#include <iostream>
#include <algorithm>
#include <list>
#include "check_self_deps.hh"
+#include "qa_notice.hh"
using namespace paludis;
-using std::cout;
-using std::cerr;
-using std::endl;
-struct SelfDepsChecker :
- DepAtomVisitorTypes::ConstVisitor
+class SelfDepsChecker :
+ public DepAtomVisitorTypes::ConstVisitor
{
- const Environment * const env;
- const QualifiedPackageName p;
- std::list<std::string> bad_deps;
- bool in_block;
-
- SelfDepsChecker(const Environment * const e, const QualifiedPackageName & pp) :
- env(e),
- p(pp),
- in_block(false)
- {
- }
+ private:
+ const Environment * const _env;
+ const QualifiedPackageName _p;
+ std::list<std::string> _bad_deps;
+ bool _in_block;
+ QANoticeLevel _level;
+
+ public:
+ const std::list<std::string> & bad_deps;
+ const QANoticeLevel & level;
+
+ SelfDepsChecker(const Environment * const e, const QualifiedPackageName & pp) :
+ _env(e),
+ _p(pp),
+ _in_block(false),
+ _level(qal_info),
+ bad_deps(_bad_deps),
+ level(_level)
+ {
+ }
- void visit(const AllDepAtom * a)
- {
- std::for_each(a->begin(), a->end(), accept_visitor(this));
- }
+ void visit(const AllDepAtom * a)
+ {
+ std::for_each(a->begin(), a->end(), accept_visitor(this));
+ }
- void visit(const AnyDepAtom * a)
- {
- std::for_each(a->begin(), a->end(), accept_visitor(this));
- }
+ void visit(const AnyDepAtom * a)
+ {
+ std::for_each(a->begin(), a->end(), accept_visitor(this));
+ }
- void visit(const UseDepAtom * a)
- {
- std::for_each(a->begin(), a->end(), accept_visitor(this));
- }
+ void visit(const UseDepAtom * a)
+ {
+ std::for_each(a->begin(), a->end(), accept_visitor(this));
+ }
- void visit(const BlockDepAtom * a)
- {
- Save<bool> save_in_block(&in_block, true);
- a->blocked_atom()->accept(this);
- }
+ void visit(const BlockDepAtom * a)
+ {
+ Save<bool> save_in_block(&_in_block, true);
+ a->blocked_atom()->accept(this);
+ }
- void visit(const PackageDepAtom * a)
- {
- if (a->package() == p)
+ void visit(const PackageDepAtom * a)
{
- if (in_block)
- bad_deps.push_back("!" + stringify(*a));
- else
- bad_deps.push_back(stringify(*a));
+ if (a->package() == _p)
+ {
+ if (_in_block)
+ _bad_deps.push_back("!" + stringify(*a));
+ else
+ _bad_deps.push_back(stringify(*a));
+
+ if (a->version_spec_ptr() || a->slot_ptr())
+ _level = std::max(_level, qal_maybe);
+ else
+ _level = std::max(_level, qal_major);
+ }
+ }
+
+ void clear()
+ {
+ _bad_deps.clear();
+ _level = qal_info;
}
- }
};
int
@@ -87,27 +104,30 @@ check_self_deps(const Environment * const env, const PackageDatabaseEntry & e)
DepParser::parse(metadata->get(vmk_depend))->accept(&checker);
if (! checker.bad_deps.empty())
{
- cout << "[WARNING] In DEPEND for '" << e << "', self dependencies found: '"
- << join(checker.bad_deps.begin(), checker.bad_deps.end(), "', '") << "'" << endl;
- checker.bad_deps.clear();
+ *QANotices::get_instance() << QANotice(checker.level, stringify(e),
+ "DEPEND self circular: '" + join(checker.bad_deps.begin(),
+ checker.bad_deps.end(), "', '") + "'");
+ checker.clear();
ret_code |= 1;
}
DepParser::parse(metadata->get(vmk_rdepend))->accept(&checker);
if (! checker.bad_deps.empty())
{
- cout << "[WARNING] In RDEPEND for '" << e << "', self dependencies found: '"
- << join(checker.bad_deps.begin(), checker.bad_deps.end(), "', '") << "'" << endl;
- checker.bad_deps.clear();
+ *QANotices::get_instance() << QANotice(checker.level, stringify(e),
+ "RDEPEND self circular: '" + join(checker.bad_deps.begin(),
+ checker.bad_deps.end(), "', '") + "'");
+ checker.clear();
ret_code |= 1;
}
DepParser::parse(metadata->get(vmk_pdepend))->accept(&checker);
if (! checker.bad_deps.empty())
{
- cout << "[WARNING] In PDEPEND for '" << e << "', self dependencies found: '"
- << join(checker.bad_deps.begin(), checker.bad_deps.end(), "', '") << "'" << endl;
- checker.bad_deps.clear();
+ *QANotices::get_instance() << QANotice(checker.level, stringify(e),
+ "PDEPEND self circular: '" + join(checker.bad_deps.begin(),
+ checker.bad_deps.end(), "', '") + "'");
+ checker.clear();
ret_code |= 1;
}
diff --git a/src/qualudis/qa_notice.cc b/src/qualudis/qa_notice.cc
new file mode 100644
index 0000000..f70aa8e
--- /dev/null
+++ b/src/qualudis/qa_notice.cc
@@ -0,0 +1,74 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+#include "qa_notice.hh"
+#include <ostream>
+#include <algorithm>
+#include <iterator>
+
+QANotices::QANotices()
+{
+}
+
+QANotices::~QANotices()
+{
+}
+
+std::ostream &
+operator<< (std::ostream & s, const QANotice & n)
+{
+ do
+ {
+ switch (n._level)
+ {
+ case qal_info:
+ s << "info: ";
+ continue;
+
+ case qal_maybe:
+ s << "maybe: ";
+ continue;
+
+ case qal_minor:
+ s << "minor: ";
+ continue;
+
+ case qal_major:
+ s << "major: ";
+ continue;
+
+ case qal_fatal:
+ s << "fatal: ";
+ continue;
+ }
+ throw paludis::InternalError(PALUDIS_HERE, "Bad n.level");
+
+ } while (false);
+
+ s << n._affected << ":\n " << n._message;
+ return s;
+}
+
+bool
+QANotice::operator< (const QANotice & other) const
+{
+ if (_level < other._level)
+ return true;
+ if (_level > other._level)
+ return false;
+
+ if (_affected < other._affected)
+ return true;
+ if (_affected > other._affected)
+ return false;
+
+ return _message < other._message;
+}
+
+std::ostream &
+operator<< (std::ostream & s, const QANotices & n)
+{
+ std::copy(n._notices.begin(), n._notices.end(),
+ std::ostream_iterator<QANotice>(s, "\n"));
+ return s;
+}
+
diff --git a/src/qualudis/qa_notice.hh b/src/qualudis/qa_notice.hh
new file mode 100644
index 0000000..5595d27
--- /dev/null
+++ b/src/qualudis/qa_notice.hh
@@ -0,0 +1,91 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2006 Ciaran McCreesh <ciaranm@gentoo.org>
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis 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 PALUDIS_GUARD_SRC_QUALUDIS_QA_NOTICE_HH
+#define PALUDIS_GUARD_SRC_QUALUDIS_QA_NOTICE_HH 1
+
+#include <paludis/paludis.hh>
+#include <string>
+#include <deque>
+#include <iosfwd>
+
+/**
+ * Different levels for QANotice messages.
+ *
+ * Keep these in order, least severe first. Several methods rely upon
+ * std::max() to determine which message is more severe.
+ */
+enum QANoticeLevel
+{
+ qal_info, ///< Information messages
+ qal_maybe, ///< May or may not be a problem
+ qal_minor, ///< Minor (usually syntax) issues
+ qal_major, ///< Serious issues
+ qal_fatal ///< Error preventing further QA checks
+};
+
+class QANotice
+{
+ friend std::ostream & operator<< (std::ostream &, const QANotice &);
+
+ private:
+ const QANoticeLevel _level;
+ const std::string _affected;
+ const std::string _message;
+
+ public:
+ QANotice(const QANoticeLevel l, const std::string & affected, const std::string & m) :
+ _level(l),
+ _affected(affected),
+ _message(m)
+ {
+ }
+
+ bool operator< (const QANotice &) const;
+};
+
+class QANotices :
+ public paludis::InstantiationPolicy<QANotices, paludis::instantiation_method::SingletonAsNeededTag>
+{
+ friend class paludis::InstantiationPolicy<QANotices, paludis::instantiation_method::SingletonAsNeededTag>;
+ friend std::ostream & operator<< (std::ostream &, const QANotices &);
+
+ private:
+ std::multiset<QANotice> _notices;
+
+ QANotices();
+
+ ~QANotices();
+
+ public:
+ QANotices &
+ operator<< (const QANotice & n)
+ {
+ _notices.insert(n);
+ return *this;
+ }
+};
+
+std::ostream &
+operator<< (std::ostream &, const QANotice &);
+
+std::ostream &
+operator<< (std::ostream &, const QANotices &);
+
+#endif
diff --git a/src/qualudis/qualudis.cc b/src/qualudis/qualudis.cc
index cd1144e..13d5f1a 100644
--- a/src/qualudis/qualudis.cc
+++ b/src/qualudis/qualudis.cc
@@ -27,6 +27,7 @@
#include "qualudis_command_line.hh"
#include "check_deps_exist.hh"
#include "check_self_deps.hh"
+#include "qa_notice.hh"
#include "config.h"
using namespace paludis;
@@ -55,55 +56,85 @@ do_check()
FSEntry cwd(FSEntry::cwd());
QualifiedPackageName qpn("x/x");
- try
- {
- PackageNamePart package(cwd.basename());
- CategoryNamePart category(FSEntry(cwd.dirname()).basename());
-
- qpn = category + package;
- }
- catch (const NameError & e)
- {
- cout << "[FATAL] Caught name error: '" << e.message() << "' (" <<
- e.what() << "), skipping further tests";
- return 1;
- }
-
- std::cout << "QA checks for " << qpn << ":" << std::endl;
-
- if (! std::count_if(DirIterator(cwd), DirIterator(), IsFileWithExtension(".ebuild")))
- {
- cout << "[FATAL] No ebuilds found in '" << cwd << "', skipping further tests" << endl;
- return 1;
- }
-
- QAEnvironment env(cwd.dirname().dirname());
-
- for (DirIterator d(cwd), d_end ; d != d_end ; ++d)
+ do
{
- if (IsFileWithExtension(stringify(qpn.get<qpn_package>()) + "-", ".ebuild")(d->basename()))
+ try
{
- PackageDatabaseEntry e(qpn, VersionSpec(strip_leading_string(
- strip_trailing_string(d->basename(), ".ebuild"),
- stringify(qpn.get<qpn_package>()) + "-")),
- env.package_database()->favourite_repository());
+ PackageNamePart package(cwd.basename());
+ CategoryNamePart category(FSEntry(cwd.dirname()).basename());
- ret_code |= check_deps_exist(&env, e);
- ret_code |= check_self_deps(&env, e);
+ qpn = category + package;
}
- else if (d->basename() == "ChangeLog")
+ catch (const NameError & e)
{
-
+ *QANotices::get_instance() << QANotice(qal_fatal, stringify(cwd),
+ "Bad category or package name: '" +
+ stringify(e.message()) + "' (" + stringify(e.what()) + ")");
+ ret_code |= 1;
+ break;
}
- else if (d->basename() == "files")
- {
- }
- else
+ std::cout << "QA checks for " << qpn << ":" << std::endl;
+
+ if (! std::count_if(DirIterator(cwd), DirIterator(), IsFileWithExtension(".ebuild")))
{
+ *QANotices::get_instance() << QANotice(qal_fatal, stringify(cwd), "No ebuilds found");
+ ret_code |= 1;
+ break;
+ }
+ QAEnvironment env(cwd.dirname().dirname());
+
+ for (DirIterator d(cwd), d_end ; d != d_end ; ++d)
+ {
+ if (IsFileWithExtension(stringify(qpn.get<qpn_package>()) + "-", ".ebuild")(d->basename()))
+ {
+ PackageDatabaseEntry e(qpn, VersionSpec(strip_leading_string(
+ strip_trailing_string(d->basename(), ".ebuild"),
+ stringify(qpn.get<qpn_package>()) + "-")),
+ env.package_database()->favourite_repository());
+
+ ret_code |= check_deps_exist(&env, e);
+ ret_code |= check_self_deps(&env, e);
+ }
+ else if (d->basename() == "ChangeLog" || d->basename() == "Manifest")
+ {
+ if (! d->is_regular_file())
+ {
+ *QANotices::get_instance() << QANotice(qal_major, stringify(*d),
+ "Not a regular file");
+ ret_code |= 1;
+ }
+ }
+ else if (d->basename() == "metadata.xml")
+ {
+ if (! d->is_regular_file())
+ {
+ *QANotices::get_instance() << QANotice(qal_major, stringify(*d),
+ "Not a regular file");
+ ret_code |= 1;
+ }
+ }
+ else if (d->basename() == "files" || d->basename() == "CVS")
+ {
+ if (! d->is_directory())
+ {
+ *QANotices::get_instance() << QANotice(qal_major, stringify(*d),
+ "Not a directory");
+ ret_code |= 1;
+ }
+ }
+ else
+ {
+ *QANotices::get_instance() << QANotice(qal_minor, stringify(*d),
+ "Not a recognised name");
+ ret_code |= 1;
+ }
}
- }
+
+ } while (false);
+
+ cout << *QANotices::get_instance() << endl;
return ret_code;
}