aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2006-02-10 01:30:51 +0000
committerAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2006-02-10 01:30:51 +0000
commitde1fde1d9024296a71f67e39de64d31c7f935721 (patch)
tree7d66c33204c62c529bc9bab56fde60c32ca66907
parent751d9d20da4554ad835e456c8a86bc256c65533a (diff)
downloadpaludis-de1fde1d9024296a71f67e39de64d31c7f935721.tar.gz
paludis-de1fde1d9024296a71f67e39de64d31c7f935721.tar.xz
More work on qualudis. Still not sanely usable.
-rw-r--r--src/qualudis/Makefile.am2
-rw-r--r--src/qualudis/check_deps_exist.cc26
-rw-r--r--src/qualudis/check_deps_exist.hh2
-rw-r--r--src/qualudis/check_metadata.cc131
-rw-r--r--src/qualudis/check_metadata.hh28
-rw-r--r--src/qualudis/check_self_deps.cc12
-rw-r--r--src/qualudis/check_self_deps.hh2
-rw-r--r--src/qualudis/check_visibility.cc155
-rw-r--r--src/qualudis/check_visibility.hh28
-rw-r--r--src/qualudis/qualudis.cc30
10 files changed, 390 insertions, 26 deletions
diff --git a/src/qualudis/Makefile.am b/src/qualudis/Makefile.am
index bfbf52c..3293b24 100644
--- a/src/qualudis/Makefile.am
+++ b/src/qualudis/Makefile.am
@@ -8,7 +8,9 @@ bin_PROGRAMS = qualudis
qualudis_SOURCES = \
check_deps_exist.hh check_deps_exist.cc \
+ check_metadata.hh check_metadata.cc \
check_self_deps.hh check_self_deps.cc \
+ check_visibility.hh check_visibility.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 5547631..bd7f4ec 100644
--- a/src/qualudis/check_deps_exist.cc
+++ b/src/qualudis/check_deps_exist.cc
@@ -33,6 +33,8 @@ class DepExistsChecker :
const Environment * const _env;
std::list<std::string> _bad_deps;
bool _in_block;
+ bool _in_any_of;
+ bool _at_least_one_ok;
QANoticeLevel _level;
public:
@@ -55,7 +57,12 @@ class DepExistsChecker :
void visit(const AnyDepAtom * a)
{
+ Save<bool> save_in_any_of(&_in_any_of, true);
+ Save<bool> save_at_least_one_ok(&_at_least_one_ok, false);
std::for_each(a->begin(), a->end(), accept_visitor(this));
+
+ if (a->begin() != a->end() && ! _at_least_one_ok)
+ _level = std::max(level, qal_major);
}
void visit(const UseDepAtom * a)
@@ -78,12 +85,19 @@ class DepExistsChecker :
_bad_deps.push_back("!" + stringify(*a));
_level = std::max(_level, qal_maybe);
}
+ else if (_in_any_of)
+ {
+ _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);
}
}
+ else
+ _at_least_one_ok = true;
}
void clear()
@@ -93,10 +107,10 @@ class DepExistsChecker :
}
};
-int
+bool
check_deps_exist(const Environment * const env, const PackageDatabaseEntry & e)
{
- int ret_code(0);
+ bool ok(true);
VersionMetadata::ConstPointer metadata(env->package_database()->fetch_metadata(e));
DepExistsChecker checker(env);
@@ -107,7 +121,7 @@ check_deps_exist(const Environment * const env, const PackageDatabaseEntry & e)
"Nonexistent DEPEND entries: " + join(checker.bad_deps.begin(),
checker.bad_deps.end(), "', '") + "'");
checker.clear();
- ret_code |= 1;
+ ok = false;
}
DepParser::parse(metadata->get(vmk_rdepend))->accept(&checker);
@@ -117,7 +131,7 @@ check_deps_exist(const Environment * const env, const PackageDatabaseEntry & e)
"Nonexistent RDEPEND entries: " + join(checker.bad_deps.begin(),
checker.bad_deps.end(), "', '") + "'");
checker.clear();
- ret_code |= 1;
+ ok = false;
}
DepParser::parse(metadata->get(vmk_pdepend))->accept(&checker);
@@ -127,9 +141,9 @@ check_deps_exist(const Environment * const env, const PackageDatabaseEntry & e)
"Nonexistent PDEPEND entries: " + join(checker.bad_deps.begin(),
checker.bad_deps.end(), "', '") + "'");
checker.clear();
- ret_code |= 1;
+ ok = false;
}
- return ret_code;
+ return ok;
}
diff --git a/src/qualudis/check_deps_exist.hh b/src/qualudis/check_deps_exist.hh
index b4b00fd..9c2fd70 100644
--- a/src/qualudis/check_deps_exist.hh
+++ b/src/qualudis/check_deps_exist.hh
@@ -22,7 +22,7 @@
#include <paludis/paludis.hh>
-int
+bool
check_deps_exist(const paludis::Environment * const env, const paludis::PackageDatabaseEntry & e);
#endif
diff --git a/src/qualudis/check_metadata.cc b/src/qualudis/check_metadata.cc
new file mode 100644
index 0000000..0de2764
--- /dev/null
+++ b/src/qualudis/check_metadata.cc
@@ -0,0 +1,131 @@
+/* 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
+ */
+
+#include "check_metadata.hh"
+#include "qa_notice.hh"
+
+using namespace paludis;
+
+bool
+check_metadata(const Environment * const env, const PackageDatabaseEntry & e)
+{
+ bool ok(true);
+ VersionMetadata::ConstPointer metadata(0);
+
+ do
+ {
+ try
+ {
+ metadata = env->package_database()->fetch_metadata(e);
+ if ("UNKNOWN" == metadata->get(vmk_eapi))
+ {
+ *QANotices::get_instance() << QANotice(qal_fatal, stringify(e),
+ "Couldn't generate metadata");
+ ok = false;
+ break;
+ }
+ }
+ catch (const paludis::Exception & x)
+ {
+ *QANotices::get_instance() << QANotice(qal_fatal, stringify(e),
+ "Error generating metadata: " + x.message());
+ ok = false;
+ break;
+ }
+
+ try
+ {
+ DepParser::parse(metadata->get(vmk_depend));
+ }
+ catch (const paludis::Exception & x)
+ {
+ *QANotices::get_instance() << QANotice(qal_fatal, stringify(e),
+ "Error parsing DEPEND: " + x.message());
+ ok = false;
+ }
+
+ try
+ {
+ DepParser::parse(metadata->get(vmk_rdepend));
+ }
+ catch (const paludis::Exception & x)
+ {
+ *QANotices::get_instance() << QANotice(qal_fatal, stringify(e),
+ "Error parsing RDEPEND: " + x.message());
+ ok = false;
+ }
+
+ try
+ {
+ DepParser::parse(metadata->get(vmk_pdepend));
+ }
+ catch (const paludis::Exception & x)
+ {
+ *QANotices::get_instance() << QANotice(qal_fatal, stringify(e),
+ "Error parsing PDEPEND: " + x.message());
+ ok = false;
+ }
+
+ if (! ok)
+ break;
+
+ try
+ {
+ DepParserOptions opts;
+ opts.set(dpo_qualified_package_names);
+ DepParser::parse(metadata->get(vmk_provide), opts);
+ }
+ catch (const paludis::Exception & x)
+ {
+ *QANotices::get_instance() << QANotice(qal_fatal, stringify(e),
+ "Error parsing PROVIDE: " + x.message());
+ ok = false;
+ }
+
+ try
+ {
+ std::set<UseFlagName> iuse(metadata->begin_iuse(), metadata->end_iuse());
+ }
+ catch (const paludis::Exception & x)
+ {
+ *QANotices::get_instance() << QANotice(qal_fatal, stringify(e),
+ "Error parsing IUSE: " + x.message());
+ ok = false;
+ }
+
+ try
+ {
+ std::set<KeywordName> keywords(metadata->begin_keywords(), metadata->end_keywords());
+
+ if (keywords.empty())
+ *QANotices::get_instance() << QANotice(qal_minor, stringify(e),
+ "KEYWORDS is empty");
+ }
+ catch (const paludis::Exception & x)
+ {
+ *QANotices::get_instance() << QANotice(qal_fatal, stringify(e),
+ "Error parsing KEYWORDS: " + x.message());
+ ok = false;
+ }
+
+ } while (false);
+
+ return ok;
+}
+
diff --git a/src/qualudis/check_metadata.hh b/src/qualudis/check_metadata.hh
new file mode 100644
index 0000000..b2e73fc
--- /dev/null
+++ b/src/qualudis/check_metadata.hh
@@ -0,0 +1,28 @@
+/* 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_CHECK_METADATA_HH
+#define PALUDIS_GUARD_SRC_QUALUDIS_CHECK_METADATA_HH 1
+
+#include <paludis/paludis.hh>
+
+bool
+check_metadata(const paludis::Environment * const env, const paludis::PackageDatabaseEntry & e);
+
+#endif
diff --git a/src/qualudis/check_self_deps.cc b/src/qualudis/check_self_deps.cc
index 2456875..0ac1e6d 100644
--- a/src/qualudis/check_self_deps.cc
+++ b/src/qualudis/check_self_deps.cc
@@ -94,10 +94,10 @@ class SelfDepsChecker :
}
};
-int
+bool
check_self_deps(const Environment * const env, const PackageDatabaseEntry & e)
{
- int ret_code(0);
+ bool ok(true);
VersionMetadata::ConstPointer metadata(env->package_database()->fetch_metadata(e));
SelfDepsChecker checker(env, e.get<pde_name>());
@@ -108,7 +108,7 @@ check_self_deps(const Environment * const env, const PackageDatabaseEntry & e)
"DEPEND self circular: '" + join(checker.bad_deps.begin(),
checker.bad_deps.end(), "', '") + "'");
checker.clear();
- ret_code |= 1;
+ ok = false;
}
DepParser::parse(metadata->get(vmk_rdepend))->accept(&checker);
@@ -118,7 +118,7 @@ check_self_deps(const Environment * const env, const PackageDatabaseEntry & e)
"RDEPEND self circular: '" + join(checker.bad_deps.begin(),
checker.bad_deps.end(), "', '") + "'");
checker.clear();
- ret_code |= 1;
+ ok = false;
}
DepParser::parse(metadata->get(vmk_pdepend))->accept(&checker);
@@ -128,9 +128,9 @@ check_self_deps(const Environment * const env, const PackageDatabaseEntry & e)
"PDEPEND self circular: '" + join(checker.bad_deps.begin(),
checker.bad_deps.end(), "', '") + "'");
checker.clear();
- ret_code |= 1;
+ ok = false;
}
- return ret_code;
+ return ok;
}
diff --git a/src/qualudis/check_self_deps.hh b/src/qualudis/check_self_deps.hh
index 8caf705..ff4d32d 100644
--- a/src/qualudis/check_self_deps.hh
+++ b/src/qualudis/check_self_deps.hh
@@ -22,7 +22,7 @@
#include <paludis/paludis.hh>
-int
+bool
check_self_deps(const paludis::Environment * const env, const paludis::PackageDatabaseEntry & e);
#endif
diff --git a/src/qualudis/check_visibility.cc b/src/qualudis/check_visibility.cc
new file mode 100644
index 0000000..518acf5
--- /dev/null
+++ b/src/qualudis/check_visibility.cc
@@ -0,0 +1,155 @@
+/* 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
+ */
+
+#include "check_visibility.hh"
+#include "qa_notice.hh"
+
+using namespace paludis;
+
+class VisibilityChecker :
+ public DepAtomVisitorTypes::ConstVisitor
+{
+ private:
+ const Environment * const _env;
+ bool _ok;
+ std::list<std::string> _bad_deps;
+
+ public:
+ const bool & ok;
+ const std::list<std::string> & bad_deps;
+
+ VisibilityChecker(const Environment * const e) :
+ _env(e),
+ _ok(true),
+ ok(_ok),
+ bad_deps(_bad_deps)
+ {
+ }
+
+ void visit(const AllDepAtom * a)
+ {
+ std::for_each(a->begin(), a->end(), accept_visitor(this));
+ }
+
+ void visit(const AnyDepAtom * a)
+ {
+ bool at_least_one_match(false), local_ok(false);
+
+ for (CompositeDepAtom::Iterator i(a->begin()), i_end(a->end()) ;
+ i != i_end ; ++i)
+ {
+ const UseDepAtom * p;
+ if (((p = (*i)->as_use_dep_atom())))
+ {
+ Save<bool> save_ok(&_ok, true);
+ accept_visitor(this)(i->raw_pointer());
+ local_ok |= ok;
+ at_least_one_match = true;
+ }
+ else
+ {
+ Save<bool> save_ok(&_ok, true);
+ accept_visitor(this)(i->raw_pointer());
+ local_ok |= ok;
+ at_least_one_match = true;
+ }
+ }
+
+ if (! ((! at_least_one_match) || local_ok))
+ _ok = false;
+ }
+
+ void visit(const UseDepAtom * a)
+ {
+ std::for_each(a->begin(), a->end(), accept_visitor(this));
+ }
+
+ void visit(const BlockDepAtom *)
+ {
+ }
+
+ void visit(const PackageDepAtom * a)
+ {
+ PackageDatabaseEntryCollection::ConstPointer m(0);
+ if (((m = _env->package_database()->query(a)))->empty())
+ _ok = false;
+ else
+ {
+ _ok = false;
+ for (PackageDatabaseEntryCollection::Iterator mm(m->begin()), mm_end(m->end()) ;
+ mm != mm_end ; ++mm)
+ if (! _env->mask_reasons(*mm).any())
+ {
+ _ok = true;
+ break;
+ }
+ }
+
+ if (! _ok)
+ _bad_deps.push_back(stringify(*a));
+ }
+
+ void clear()
+ {
+ _ok = true;
+ _bad_deps.clear();
+ }
+};
+
+bool
+check_visibility(const paludis::Environment * const env, const paludis::PackageDatabaseEntry & e)
+{
+ bool ok = true;
+
+ VersionMetadata::ConstPointer metadata(env->package_database()->fetch_metadata(e));
+ VisibilityChecker checker(env);
+
+ DepParser::parse(metadata->get(vmk_depend))->accept(&checker);
+ if (! checker.ok)
+ {
+ *QANotices::get_instance() << QANotice(qal_major, stringify(e),
+ "Invisible DEPEND entries: " + join(checker.bad_deps.begin(),
+ checker.bad_deps.end(), "', '") + "'");
+ checker.clear();
+ ok = false;
+ }
+
+ DepParser::parse(metadata->get(vmk_rdepend))->accept(&checker);
+ if (! checker.bad_deps.empty())
+ {
+ *QANotices::get_instance() << QANotice(qal_major, stringify(e),
+ "Invisible RDEPEND entries: " + join(checker.bad_deps.begin(),
+ checker.bad_deps.end(), "', '") + "'");
+ checker.clear();
+ ok = false;
+ }
+
+ DepParser::parse(metadata->get(vmk_pdepend))->accept(&checker);
+ if (! checker.bad_deps.empty())
+ {
+ *QANotices::get_instance() << QANotice(qal_major, stringify(e),
+ "Invisible PDEPEND entries: " + join(checker.bad_deps.begin(),
+ checker.bad_deps.end(), "', '") + "'");
+ checker.clear();
+ ok = false;
+ }
+
+ return ok;
+}
+
diff --git a/src/qualudis/check_visibility.hh b/src/qualudis/check_visibility.hh
new file mode 100644
index 0000000..0661dac
--- /dev/null
+++ b/src/qualudis/check_visibility.hh
@@ -0,0 +1,28 @@
+/* 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_CHECK_VISIBILITY_HH
+#define PALUDIS_GUARD_SRC_QUALUDIS_CHECK_VISIBILITY_HH 1
+
+#include <paludis/paludis.hh>
+
+bool
+check_visibility(const paludis::Environment * const env, const paludis::PackageDatabaseEntry & e);
+
+#endif
diff --git a/src/qualudis/qualudis.cc b/src/qualudis/qualudis.cc
index 13d5f1a..48a1f38 100644
--- a/src/qualudis/qualudis.cc
+++ b/src/qualudis/qualudis.cc
@@ -25,8 +25,10 @@
#include <algorithm>
#include "qualudis_command_line.hh"
+#include "check_metadata.hh"
#include "check_deps_exist.hh"
#include "check_self_deps.hh"
+#include "check_visibility.hh"
#include "qa_notice.hh"
#include "config.h"
@@ -49,10 +51,10 @@ struct DoVersion
{
};
-int
+bool
do_check()
{
- int ret_code(0);
+ bool ok(true);
FSEntry cwd(FSEntry::cwd());
QualifiedPackageName qpn("x/x");
@@ -70,7 +72,7 @@ do_check()
*QANotices::get_instance() << QANotice(qal_fatal, stringify(cwd),
"Bad category or package name: '" +
stringify(e.message()) + "' (" + stringify(e.what()) + ")");
- ret_code |= 1;
+ ok = false;
break;
}
@@ -79,7 +81,7 @@ do_check()
if (! std::count_if(DirIterator(cwd), DirIterator(), IsFileWithExtension(".ebuild")))
{
*QANotices::get_instance() << QANotice(qal_fatal, stringify(cwd), "No ebuilds found");
- ret_code |= 1;
+ ok = false;
break;
}
@@ -94,8 +96,12 @@ do_check()
stringify(qpn.get<qpn_package>()) + "-")),
env.package_database()->favourite_repository());
- ret_code |= check_deps_exist(&env, e);
- ret_code |= check_self_deps(&env, e);
+ if (! ((ok &= check_metadata(&env, e))))
+ break;
+
+ ok &= check_deps_exist(&env, e);
+ ok &= check_self_deps(&env, e);
+ ok &= check_visibility(&env, e);
}
else if (d->basename() == "ChangeLog" || d->basename() == "Manifest")
{
@@ -103,7 +109,7 @@ do_check()
{
*QANotices::get_instance() << QANotice(qal_major, stringify(*d),
"Not a regular file");
- ret_code |= 1;
+ ok = false;
}
}
else if (d->basename() == "metadata.xml")
@@ -112,7 +118,7 @@ do_check()
{
*QANotices::get_instance() << QANotice(qal_major, stringify(*d),
"Not a regular file");
- ret_code |= 1;
+ ok = false;
}
}
else if (d->basename() == "files" || d->basename() == "CVS")
@@ -121,14 +127,14 @@ do_check()
{
*QANotices::get_instance() << QANotice(qal_major, stringify(*d),
"Not a directory");
- ret_code |= 1;
+ ok = false;
}
}
else
{
*QANotices::get_instance() << QANotice(qal_minor, stringify(*d),
"Not a recognised name");
- ret_code |= 1;
+ ok = false;
}
}
@@ -136,7 +142,7 @@ do_check()
cout << *QANotices::get_instance() << endl;
- return ret_code;
+ return ok;
}
int main(int argc, char *argv[])
@@ -162,7 +168,7 @@ int main(int argc, char *argv[])
if (! QualudisCommandLine::get_instance()->empty())
throw DoHelp("check action takes no parameters");
- return do_check();
+ return do_check() ? EXIT_SUCCESS : EXIT_FAILURE;
}
throw InternalError(__PRETTY_FUNCTION__, "no action?");