Commit 678cd10d authored by Rusty Russell's avatar Rusty Russell

ccanlint: exit with non-zero exit status if a test fails.

This means we change some minor tests to "never fail", eg. whitespace
or documentation tests.  Note that pass/fail is independent of the
score for a test.
parent 7ce5cb9d
...@@ -161,9 +161,9 @@ static bool run_test(struct ccanlint *i, ...@@ -161,9 +161,9 @@ static bool run_test(struct ccanlint *i,
printf("%s%s", score->error, printf("%s%s", score->error,
strends(score->error, "\n") ? "" : "\n"); strends(score->error, "\n") ? "" : "\n");
} }
if (!quiet && !score->pass && i->handle)
i->handle(m, score);
} }
if (!quiet && score->score < score->total && i->handle)
i->handle(m, score);
*running_score += score->score; *running_score += score->score;
*running_total += score->total; *running_total += score->total;
...@@ -584,7 +584,7 @@ static char *opt_set_const_charp(const char *arg, const char **p) ...@@ -584,7 +584,7 @@ static char *opt_set_const_charp(const char *arg, const char **p)
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
bool summary = false; bool summary = false, pass = true;
unsigned int score = 0, total_score = 0; unsigned int score = 0, total_score = 0;
struct manifest *m; struct manifest *m;
struct ccanlint *i; struct ccanlint *i;
...@@ -675,8 +675,8 @@ int main(int argc, char *argv[]) ...@@ -675,8 +675,8 @@ int main(int argc, char *argv[])
add_info_options(m->info_file, !target); add_info_options(m->info_file, !target);
while ((i = get_next_test(&normal_tests)) != NULL) while ((i = get_next_test(&normal_tests)) != NULL)
run_test(i, summary, &score, &total_score, m); pass &= run_test(i, summary, &score, &total_score, m);
printf("%sTotal score: %u/%u\n", prefix, score, total_score); printf("%sTotal score: %u/%u\n", prefix, score, total_score);
return 0; return pass ? 0 : 1;
} }
...@@ -44,18 +44,26 @@ struct manifest { ...@@ -44,18 +44,26 @@ struct manifest {
struct list_head deps; struct list_head deps;
}; };
/* Get the manifest for a given directory. */
struct manifest *get_manifest(const void *ctx, const char *dir); struct manifest *get_manifest(const void *ctx, const char *dir);
/* Error in a particular file: stored off score->per_file_errors. */
struct file_error { struct file_error {
struct list_node list; struct list_node list;
struct ccan_file *file; struct ccan_file *file;
unsigned int line; unsigned int line;
}; };
/* The score for an individual test. */
struct score { struct score {
/* Starts as false: if not set to true, ccanlint exits non-zero.
* Thus it is usually set for compilation or other serious failures. */
bool pass; bool pass;
/* Starts at 0 and 1 respectively. */
unsigned int score, total; unsigned int score, total;
/* The error message to print. */
char *error; char *error;
/* Per file errors, set by score_file_error() */
struct list_head per_file_errors; struct list_head per_file_errors;
}; };
...@@ -86,7 +94,7 @@ struct ccanlint { ...@@ -86,7 +94,7 @@ struct ccanlint {
/* If not set, we'll give an error if they try to set options. */ /* If not set, we'll give an error if they try to set options. */
bool takes_options; bool takes_options;
/* comma-separated list of dependency keys. */ /* Space-separated list of dependency keys. */
const char *needs; const char *needs;
/* Internal use fields: */ /* Internal use fields: */
......
...@@ -37,6 +37,9 @@ static void check_depends_accurate(struct manifest *m, ...@@ -37,6 +37,9 @@ static void check_depends_accurate(struct manifest *m,
{ {
struct list_head *list; struct list_head *list;
/* FIXME: This isn't reliable enough with #ifdefs, so we don't fail. */
score->pass = true;
foreach_ptr(list, &m->c_files, &m->h_files, foreach_ptr(list, &m->c_files, &m->h_files,
&m->run_tests, &m->api_tests, &m->run_tests, &m->api_tests,
&m->compile_ok_tests, &m->compile_fail_tests, &m->compile_ok_tests, &m->compile_fail_tests,
...@@ -63,7 +66,6 @@ static void check_depends_accurate(struct manifest *m, ...@@ -63,7 +66,6 @@ static void check_depends_accurate(struct manifest *m,
} }
if (!score->error) { if (!score->error) {
score->pass = true;
score->score = score->total; score->score = score->total;
} }
} }
......
...@@ -94,9 +94,10 @@ static void extract_examples(struct manifest *m, ...@@ -94,9 +94,10 @@ static void extract_examples(struct manifest *m,
} }
} }
/* We don't fail ccanlint for this. */
score->pass = true;
if (have_info_example && have_header_example) { if (have_info_example && have_header_example) {
score->score = score->total; score->score = score->total;
score->pass = true;
return; return;
} }
...@@ -106,8 +107,6 @@ static void extract_examples(struct manifest *m, ...@@ -106,8 +107,6 @@ static void extract_examples(struct manifest *m,
score_file_error(score, mainh, 0, "No Example: section"); score_file_error(score, mainh, 0, "No Example: section");
score->score = have_info_example + have_header_example; score->score = have_info_example + have_header_example;
/* We pass if we find any example. */
score->pass = score->score != 0;
} }
struct ccanlint examples_exist = { struct ccanlint examples_exist = {
......
...@@ -25,6 +25,9 @@ static void check_hash_if(struct manifest *m, ...@@ -25,6 +25,9 @@ static void check_hash_if(struct manifest *m,
"\n\t(#if works like #ifdef, but with gcc's -Wundef, we can detect\n" "\n\t(#if works like #ifdef, but with gcc's -Wundef, we can detect\n"
"\tmistyped or unknown configuration options)"; "\tmistyped or unknown configuration options)";
/* We don't fail ccanlint for this. */
score->pass = true;
foreach_ptr(list, &m->c_files, &m->h_files, foreach_ptr(list, &m->c_files, &m->h_files,
&m->run_tests, &m->api_tests, &m->run_tests, &m->api_tests,
&m->compile_ok_tests, &m->compile_fail_tests, &m->compile_ok_tests, &m->compile_fail_tests,
...@@ -60,7 +63,6 @@ static void check_hash_if(struct manifest *m, ...@@ -60,7 +63,6 @@ static void check_hash_if(struct manifest *m,
} }
if (!score->error) { if (!score->error) {
score->pass = true;
score->score = score->total; score->score = score->total;
} }
} }
......
...@@ -179,11 +179,13 @@ static void check_idempotent(struct manifest *m, ...@@ -179,11 +179,13 @@ static void check_idempotent(struct manifest *m,
{ {
struct ccan_file *f; struct ccan_file *f;
/* We don't fail ccanlint for this. */
score->pass = true;
list_for_each(&m->h_files, f, list) { list_for_each(&m->h_files, f, list) {
check_idem(f, score); check_idem(f, score);
} }
if (!score->error) { if (!score->error) {
score->pass = true;
score->score = score->total; score->score = score->total;
} }
} }
......
...@@ -67,6 +67,9 @@ static void check_info_documentation_exists(struct manifest *m, ...@@ -67,6 +67,9 @@ static void check_info_documentation_exists(struct manifest *m,
struct doc_section *d; struct doc_section *d;
bool summary = false, description = false; bool summary = false, description = false;
/* We don't fail ccanlint for this. */
score->pass = true;
list_for_each(infodocs, d, list) { list_for_each(infodocs, d, list) {
if (!streq(d->function, m->basename)) if (!streq(d->function, m->basename))
continue; continue;
...@@ -78,7 +81,6 @@ static void check_info_documentation_exists(struct manifest *m, ...@@ -78,7 +81,6 @@ static void check_info_documentation_exists(struct manifest *m,
if (summary && description) { if (summary && description) {
score->score = score->total; score->score = score->total;
score->pass = true;
} else if (!summary) { } else if (!summary) {
score->error = talloc_strdup(score, score->error = talloc_strdup(score,
"_info file has no module documentation.\n\n" "_info file has no module documentation.\n\n"
......
...@@ -11,8 +11,6 @@ ...@@ -11,8 +11,6 @@
#include <ccan/talloc/talloc.h> #include <ccan/talloc/talloc.h>
#include <ccan/str/str.h> #include <ccan/str/str.h>
REGISTER_TEST(license_exists);
static struct doc_section *find_license(const struct manifest *m) static struct doc_section *find_license(const struct manifest *m)
{ {
struct doc_section *d; struct doc_section *d;
...@@ -79,6 +77,8 @@ static void handle_license_link(struct manifest *m, struct score *score) ...@@ -79,6 +77,8 @@ static void handle_license_link(struct manifest *m, struct score *score)
} }
} }
extern struct ccanlint license_exists;
static void check_has_license(struct manifest *m, static void check_has_license(struct manifest *m,
bool keep, bool keep,
unsigned int *timeleft, struct score *score) unsigned int *timeleft, struct score *score)
...@@ -94,6 +94,9 @@ static void check_has_license(struct manifest *m, ...@@ -94,6 +94,9 @@ static void check_has_license(struct manifest *m,
score->error = talloc_strdup(score, "No License: tag in _info"); score->error = talloc_strdup(score, "No License: tag in _info");
return; return;
} }
/* If they have a license tag at all, we pass. */
score->pass = true;
expected = expected_link(m, d); expected = expected_link(m, d);
len = readlink(license, buf, sizeof(buf)); len = readlink(license, buf, sizeof(buf));
...@@ -157,3 +160,4 @@ struct ccanlint license_exists = { ...@@ -157,3 +160,4 @@ struct ccanlint license_exists = {
.check = check_has_license, .check = check_has_license,
.needs = "info_exists" .needs = "info_exists"
}; };
REGISTER_TEST(license_exists);
...@@ -30,6 +30,9 @@ static void check_trailing_whitespace(struct manifest *m, ...@@ -30,6 +30,9 @@ static void check_trailing_whitespace(struct manifest *m,
struct ccan_file *f; struct ccan_file *f;
unsigned int i; unsigned int i;
/* We don't fail ccanlint for this. */
score->pass = true;
foreach_ptr(list, &m->c_files, &m->h_files) { foreach_ptr(list, &m->c_files, &m->h_files) {
list_for_each(list, f, list) { list_for_each(list, f, list) {
char **lines = get_ccan_file_lines(f); char **lines = get_ccan_file_lines(f);
...@@ -42,7 +45,6 @@ static void check_trailing_whitespace(struct manifest *m, ...@@ -42,7 +45,6 @@ static void check_trailing_whitespace(struct manifest *m,
} }
} }
if (!score->error) { if (!score->error) {
score->pass = true;
score->score = score->total; score->score = score->total;
} }
} }
......
...@@ -128,9 +128,11 @@ static void build_objects_with_stringchecks(struct manifest *m, ...@@ -128,9 +128,11 @@ static void build_objects_with_stringchecks(struct manifest *m,
} }
} }
/* We don't fail ccanlint for this. */
score->pass = true;
score->total = 1; score->total = 1;
if (!errors) { if (!errors) {
score->pass = true;
score->score = !warnings; score->score = !warnings;
} }
} }
......
...@@ -104,6 +104,8 @@ static void check_tests_exist(struct manifest *m, ...@@ -104,6 +104,8 @@ static void check_tests_exist(struct manifest *m,
if (errno != ENOENT) if (errno != ENOENT)
err(1, "statting %s", test_dir); err(1, "statting %s", test_dir);
tests_exist.handle = handle_no_tests; tests_exist.handle = handle_no_tests;
/* We "pass" this. */
score->pass = true;
return; return;
} }
......
...@@ -156,9 +156,10 @@ static void do_leakcheck_vg(struct manifest *m, ...@@ -156,9 +156,10 @@ static void do_leakcheck_vg(struct manifest *m,
} }
} }
/* FIXME: We don't fail for this, since many tests leak. */
score->pass = true;
if (!leaks) { if (!leaks) {
score->score = 1; score->score = 1;
score->pass = true;
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment