Commit 453fdc02 authored by Rusty Russell's avatar Rusty Russell

ccanlint: add testdepends support.

Signed-off-by: default avatarRusty Russell <rusty@rustcorp.com.au>
parent 19902365
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
#include <string.h> #include <string.h>
#include <ctype.h> #include <ctype.h>
static bool has_dep(struct manifest *m, const char *depname) static bool has_dep(struct manifest *m, bool test_depend, const char *depname)
{ {
struct manifest *i; struct manifest *i;
...@@ -28,21 +28,20 @@ static bool has_dep(struct manifest *m, const char *depname) ...@@ -28,21 +28,20 @@ static bool has_dep(struct manifest *m, const char *depname)
if (streq(i->basename, depname)) if (streq(i->basename, depname))
return true; return true;
} }
if (test_depend) {
list_for_each(&m->test_deps, i, list) {
if (streq(i->basename, depname))
return true;
}
}
return false; return false;
} }
static void check_depends_accurate(struct manifest *m, static void check_dep_includes(struct manifest *m, struct score *score,
unsigned int *timeleft, struct score *score) struct ccan_file *f, bool test_depend)
{ {
struct list_head *list;
foreach_ptr(list, &m->c_files, &m->h_files,
&m->run_tests, &m->api_tests,
&m->compile_ok_tests, &m->compile_fail_tests,
&m->other_test_c_files) {
struct ccan_file *f;
list_for_each(list, f, list) {
unsigned int i; unsigned int i;
char **lines = get_ccan_file_lines(f); char **lines = get_ccan_file_lines(f);
struct line_info *li = get_ccan_line_info(f); struct line_info *li = get_ccan_line_info(f);
...@@ -54,7 +53,7 @@ static void check_depends_accurate(struct manifest *m, ...@@ -54,7 +53,7 @@ static void check_depends_accurate(struct manifest *m,
"ccan/+([^/]+)/", &mod)) "ccan/+([^/]+)/", &mod))
continue; continue;
if (has_dep(m, mod)) if (has_dep(m, test_depend, mod))
continue; continue;
/* FIXME: we can't be sure about /* FIXME: we can't be sure about
...@@ -62,11 +61,30 @@ static void check_depends_accurate(struct manifest *m, ...@@ -62,11 +61,30 @@ static void check_depends_accurate(struct manifest *m,
* complain. */ * complain. */
if (!li[i].cond) { if (!li[i].cond) {
score_file_error(score, f, i+1, score_file_error(score, f, i+1,
"%s not listed in _info", "%s not listed in _info", mod);
mod);
} }
} }
}
static void check_depends_accurate(struct manifest *m,
unsigned int *timeleft, struct score *score)
{
struct list_head *list;
foreach_ptr(list, &m->c_files, &m->h_files) {
struct ccan_file *f;
list_for_each(list, f, list)
check_dep_includes(m, score, f, false);
} }
foreach_ptr(list, &m->run_tests, &m->api_tests,
&m->compile_ok_tests, &m->compile_fail_tests,
&m->other_test_c_files) {
struct ccan_file *f;
list_for_each(list, f, list)
check_dep_includes(m, score, f, true);
} }
if (!score->error) { if (!score->error) {
...@@ -79,7 +97,7 @@ struct ccanlint depends_accurate = { ...@@ -79,7 +97,7 @@ struct ccanlint depends_accurate = {
.key = "depends_accurate", .key = "depends_accurate",
.name = "Module's CCAN dependencies are the only CCAN files #included", .name = "Module's CCAN dependencies are the only CCAN files #included",
.check = check_depends_accurate, .check = check_depends_accurate,
.needs = "depends_exist" .needs = "depends_exist test_depends_exist"
}; };
REGISTER_TEST(depends_accurate); REGISTER_TEST(depends_accurate);
#include <tools/ccanlint/ccanlint.h> #include <tools/ccanlint/ccanlint.h>
#include <tools/tools.h> #include <tools/tools.h>
#include <ccan/talloc/talloc.h> #include <ccan/talloc/talloc.h>
#include <ccan/foreach/foreach.h>
#include <ccan/str/str.h> #include <ccan/str/str.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
...@@ -79,19 +80,26 @@ char *build_submodule(struct manifest *m, const char *flags, ...@@ -79,19 +80,26 @@ char *build_submodule(struct manifest *m, const char *flags,
static void check_depends_built(struct manifest *m, static void check_depends_built(struct manifest *m,
unsigned int *timeleft, struct score *score) unsigned int *timeleft, struct score *score)
{ {
struct list_head *list;
foreach_ptr(list, &m->deps, &m->test_deps) {
struct manifest *i; struct manifest *i;
list_for_each(list, i, list) {
char *errstr;
list_for_each(&m->deps, i, list) { errstr = build_submodule(i, cflags, COMPILE_NORMAL);
char *errstr = build_submodule(i, cflags, COMPILE_NORMAL);
if (errstr) { if (errstr) {
score->error = talloc_asprintf(score, score->error = talloc_asprintf(score,
"Dependency %s" "Dependency %s"
" did not build:\n%s", " did not"
i->basename, errstr); " build:\n%s",
i->basename,
errstr);
return; return;
} }
} }
}
score->pass = true; score->pass = true;
score->score = score->total; score->score = score->total;
...@@ -102,7 +110,7 @@ struct ccanlint depends_build = { ...@@ -102,7 +110,7 @@ struct ccanlint depends_build = {
.name = "Module's CCAN dependencies can be found or built", .name = "Module's CCAN dependencies can be found or built",
.check = check_depends_built, .check = check_depends_built,
.can_run = can_build, .can_run = can_build,
.needs = "depends_exist" .needs = "depends_exist test_depends_exist"
}; };
REGISTER_TEST(depends_build); REGISTER_TEST(depends_build);
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
#include <tools/tools.h> #include <tools/tools.h>
#include <ccan/talloc/talloc.h> #include <ccan/talloc/talloc.h>
#include <ccan/str/str.h> #include <ccan/str/str.h>
#include <ccan/foreach/foreach.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <fcntl.h> #include <fcntl.h>
...@@ -27,23 +28,29 @@ static void check_depends_built_without_features(struct manifest *m, ...@@ -27,23 +28,29 @@ static void check_depends_built_without_features(struct manifest *m,
unsigned int *timeleft, unsigned int *timeleft,
struct score *score) struct score *score)
{ {
struct list_head *list;
struct manifest *i; struct manifest *i;
char *flags; char *flags;
flags = talloc_asprintf(score, "%s %s", cflags, flags = talloc_asprintf(score, "%s %s", cflags,
REDUCE_FEATURES_FLAGS); REDUCE_FEATURES_FLAGS);
list_for_each(&m->deps, i, list) { foreach_ptr(list, &m->deps, &m->test_deps) {
char *errstr = build_submodule(i, flags, COMPILE_NOFEAT); list_for_each(list, i, list) {
char *errstr = build_submodule(i, flags,
COMPILE_NOFEAT);
if (errstr) { if (errstr) {
score->error = talloc_asprintf(score, score->error = talloc_asprintf(score,
"Dependency %s" "Dependency %s"
" did not build:\n%s", " did not"
i->basename, errstr); " build:\n%s",
i->basename,
errstr);
return; return;
} }
} }
}
score->pass = true; score->pass = true;
score->score = score->total; score->score = score->total;
......
...@@ -14,7 +14,20 @@ ...@@ -14,7 +14,20 @@
#include <string.h> #include <string.h>
#include <ctype.h> #include <ctype.h>
static bool add_dep(struct manifest *m, const char *dep, struct score *score) static bool have_dep(struct manifest *m, const char *dep)
{
struct manifest *i;
list_for_each(&m->deps, i, list)
if (streq(i->basename, dep + strlen("ccan/")))
return true;
return false;
}
static bool add_dep(struct manifest *m,
struct list_head *deplist,
const char *dep, struct score *score)
{ {
struct stat st; struct stat st;
struct manifest *subm; struct manifest *subm;
...@@ -29,7 +42,7 @@ static bool add_dep(struct manifest *m, const char *dep, struct score *score) ...@@ -29,7 +42,7 @@ static bool add_dep(struct manifest *m, const char *dep, struct score *score)
return false; return false;
} }
subm = get_manifest(m, dir); subm = get_manifest(m, dir);
list_add_tail(&m->deps, &subm->list); list_add_tail(deplist, &subm->list);
return true; return true;
} }
...@@ -39,11 +52,32 @@ static void check_depends_exist(struct manifest *m, ...@@ -39,11 +52,32 @@ static void check_depends_exist(struct manifest *m,
{ {
unsigned int i; unsigned int i;
char **deps; char **deps;
char *updir = talloc_strdup(m, m->dir);
bool needs_tap;
if (strrchr(updir, '/')) if (safe_mode)
*strrchr(updir, '/') = '\0'; deps = get_safe_ccan_deps(m, m->dir, "depends", true);
else
deps = get_deps(m, m->dir, "depends", true,
get_or_compile_info);
for (i = 0; deps[i]; i++) {
if (!strstarts(deps[i], "ccan/"))
continue;
if (!add_dep(m, &m->deps, deps[i], score))
return;
}
score->pass = true;
score->score = score->total;
}
static void check_test_depends_exist(struct manifest *m,
unsigned int *timeleft,
struct score *score)
{
unsigned int i;
char **deps;
bool needs_tap;
/* We may need libtap for testing, unless we're "tap" */ /* We may need libtap for testing, unless we're "tap" */
if (streq(m->basename, "tap")) { if (streq(m->basename, "tap")) {
...@@ -55,16 +89,18 @@ static void check_depends_exist(struct manifest *m, ...@@ -55,16 +89,18 @@ static void check_depends_exist(struct manifest *m,
} }
if (safe_mode) if (safe_mode)
deps = get_safe_ccan_deps(m, m->dir, "depends", true); deps = get_safe_ccan_deps(m, m->dir, "testdepends", true);
else else
deps = get_deps(m, m->dir, "depends", true, deps = get_deps(m, m->dir, "testdepends", true,
get_or_compile_info); get_or_compile_info);
for (i = 0; deps[i]; i++) { for (i = 0; deps[i]; i++) {
if (!strstarts(deps[i], "ccan/")) if (!strstarts(deps[i], "ccan/"))
continue; continue;
if (!add_dep(m, deps[i], score)) /* Don't add dependency twice: we can only be on one list! */
if (!have_dep(m, deps[i])
&& !add_dep(m, &m->test_deps, deps[i], score))
return; return;
if (streq(deps[i], "ccan/tap")) { if (streq(deps[i], "ccan/tap")) {
...@@ -72,7 +108,8 @@ static void check_depends_exist(struct manifest *m, ...@@ -72,7 +108,8 @@ static void check_depends_exist(struct manifest *m,
} }
} }
if (needs_tap && !add_dep(m, "ccan/tap", score)) { if (needs_tap && !have_dep(m, "ccan/tap")
&& !add_dep(m, &m->test_deps, "ccan/tap", score)) {
return; return;
} }
...@@ -89,3 +126,13 @@ struct ccanlint depends_exist = { ...@@ -89,3 +126,13 @@ struct ccanlint depends_exist = {
}; };
REGISTER_TEST(depends_exist); REGISTER_TEST(depends_exist);
struct ccanlint test_depends_exist = {
.key = "test_depends_exist",
.name = "Module's CCAN test dependencies can be found",
.compulsory = false,
.check = check_test_depends_exist,
.needs = "depends_exist"
};
REGISTER_TEST(test_depends_exist);
...@@ -42,23 +42,30 @@ char *test_obj_list(const struct manifest *m, bool link_with_module, ...@@ -42,23 +42,30 @@ char *test_obj_list(const struct manifest *m, bool link_with_module,
list = talloc_asprintf_append(list, " %s", list = talloc_asprintf_append(list, " %s",
i->compiled[own_ctype]); i->compiled[own_ctype]);
/* Other ccan modules. */ /* Other ccan modules (normal depends). */
list_for_each(&m->deps, subm, list) { list_for_each(&m->deps, subm, list) {
if (subm->compiled[ctype]) if (subm->compiled[ctype])
list = talloc_asprintf_append(list, " %s", list = talloc_asprintf_append(list, " %s",
subm->compiled[ctype]); subm->compiled[ctype]);
} }
/* Other ccan modules (test depends). */
list_for_each(&m->test_deps, subm, list) {
if (subm->compiled[ctype])
list = talloc_asprintf_append(list, " %s",
subm->compiled[ctype]);
}
return list; return list;
} }
char *lib_list(const struct manifest *m, enum compile_type ctype) char *test_lib_list(const struct manifest *m, enum compile_type ctype)
{ {
unsigned int i; unsigned int i;
char **libs; char **libs;
char *ret = talloc_strdup(m, ""); char *ret = talloc_strdup(m, "");
libs = get_libs(m, m->dir, "depends", get_or_compile_info); libs = get_libs(m, m->dir, "testdepends", get_or_compile_info);
for (i = 0; libs[i]; i++) for (i = 0; libs[i]; i++)
ret = talloc_asprintf_append(ret, "-l%s ", libs[i]); ret = talloc_asprintf_append(ret, "-l%s ", libs[i]);
return ret; return ret;
...@@ -84,7 +91,7 @@ static bool compile(const void *ctx, ...@@ -84,7 +91,7 @@ static bool compile(const void *ctx,
if (!compile_and_link(ctx, file->fullname, ccan_dir, if (!compile_and_link(ctx, file->fullname, ccan_dir,
test_obj_list(m, link_with_module, test_obj_list(m, link_with_module,
ctype, ctype), ctype, ctype),
compiler, flags, lib_list(m, ctype), fname, compiler, flags, test_lib_list(m, ctype), fname,
output)) { output)) {
talloc_free(fname); talloc_free(fname);
return false; return false;
...@@ -111,7 +118,7 @@ static void compile_async(const void *ctx, ...@@ -111,7 +118,7 @@ static void compile_async(const void *ctx,
compile_and_link_async(file, time_ms, file->fullname, ccan_dir, compile_and_link_async(file, time_ms, file->fullname, ccan_dir,
test_obj_list(m, link_with_module, ctype, ctype), test_obj_list(m, link_with_module, ctype, ctype),
compiler, flags, lib_list(m, ctype), compiler, flags, test_lib_list(m, ctype),
file->compiled[ctype]); file->compiled[ctype]);
} }
......
...@@ -3,4 +3,4 @@ ...@@ -3,4 +3,4 @@
char *test_obj_list(const struct manifest *m, bool link_with_module, char *test_obj_list(const struct manifest *m, bool link_with_module,
enum compile_type ctype, enum compile_type own_ctype); enum compile_type ctype, enum compile_type own_ctype);
/* Library list as specified by ctype variant of _info. */ /* Library list as specified by ctype variant of _info. */
char *lib_list(const struct manifest *m, enum compile_type ctype); char *test_lib_list(const struct manifest *m, enum compile_type ctype);
...@@ -46,7 +46,7 @@ static void cov_compile(const void *ctx, ...@@ -46,7 +46,7 @@ static void cov_compile(const void *ctx,
COMPILE_NORMAL, COMPILE_NORMAL,
COMPILE_COVERAGE), COMPILE_COVERAGE),
compiler, flags, compiler, flags,
lib_list(m, COMPILE_NORMAL), test_lib_list(m, COMPILE_NORMAL),
file->compiled[COMPILE_COVERAGE]); file->compiled[COMPILE_COVERAGE]);
} }
......
...@@ -237,6 +237,7 @@ struct manifest *get_manifest(const void *ctx, const char *dir) ...@@ -237,6 +237,7 @@ struct manifest *get_manifest(const void *ctx, const char *dir)
list_head_init(&m->examples); list_head_init(&m->examples);
list_head_init(&m->mangled_examples); list_head_init(&m->mangled_examples);
list_head_init(&m->deps); list_head_init(&m->deps);
list_head_init(&m->test_deps);
len = strlen(m->dir); len = strlen(m->dir);
while (len && m->dir[len-1] == '/') while (len && m->dir[len-1] == '/')
......
...@@ -38,6 +38,7 @@ struct manifest { ...@@ -38,6 +38,7 @@ struct manifest {
/* From tests/check_depends_exist.c */ /* From tests/check_depends_exist.c */
struct list_head deps; struct list_head deps;
struct list_head test_deps;
/* From tests/license_exists.c */ /* From tests/license_exists.c */
enum license license; enum license license;
......
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