From: Rusty Russell Date: Thu, 21 Jul 2011 04:59:03 +0000 (+0930) Subject: ccanlint: check for incompatible license boilerplates within subfiles. X-Git-Url: http://git.ozlabs.org/?p=ccan;a=commitdiff_plain;h=4c1a5ebd8720c26e264c89f8256df02a93db683a;ds=sidebyside ccanlint: check for incompatible license boilerplates within subfiles. This checks to make sure you're not accidentally relicensing code; eg. it's OK (though a bit impolite) to turn a BSD-licensed file into a GPL module, but not the other way around. --- diff --git a/tools/ccanlint/licenses.c b/tools/ccanlint/licenses.c index 9bfa1d2b..c2a4871d 100644 --- a/tools/ccanlint/licenses.c +++ b/tools/ccanlint/licenses.c @@ -72,6 +72,36 @@ const struct license_info licenses[] = { }, }; +/* License compatibilty chart (simplified: we don't test that licenses between + * files are compatible). */ +bool license_compatible[LICENSE_UNKNOWN+1][LICENSE_UNKNOWN] = { +/* LGPL2+ LGPL2 LGPL3 LGPL GPL2+ GPL2 GPL3 GPL BSD MIT PD */ +/* _info says: LGPL2+ */ + { true, false,false,true, false,false,false,false,true, true, true }, +/* _info says: LGPL2 only */ + { true, true, false,true, false,false,false,false,true, true, true }, +/* _info says: LGPL3 (or any later version) */ + { true, false,true, true, false,false,false,false,true, true, true }, +/* _info says: LGPL (no version specified) */ + { true, true, true, true, false,false,false,false,true, true, true }, +/* _info says: GPL2+ */ + { true, true, true, true, true, false,false,true, true, true, true }, +/* _info says: GPL2 only */ + { true, true, true, true, true, true, false,true, true, true, true }, +/* _info says: GPL3 (or any later version) */ + { true, true, true, true, true, false,true, true, true, true, true }, +/* _info says: GPL (unknown version) */ + { true, true, true, true, true, true, true, true, true, true, true }, +/* _info says: BSD (3-clause) */ + { false,false,false,false,false,false,false,false,true, true, true }, +/* _info says: MIT */ + { false,false,false,false,false,false,false,false,false,true, true }, +/* _info says: Public domain */ + { false,false,false,false,false,false,false,false,false,false,true }, +/* _info says something we don't understand */ + { false,false,false,false,false,false,false,false,false,false,true } +}; + const char *get_ccan_simplified(struct ccan_file *f) { if (!f->simplified) { diff --git a/tools/ccanlint/licenses.h b/tools/ccanlint/licenses.h index 7b70bfac..72b14d25 100644 --- a/tools/ccanlint/licenses.h +++ b/tools/ccanlint/licenses.h @@ -26,6 +26,9 @@ struct license_info { const char *clause[NUM_CLAUSES]; }; +/* Is [project license][file license] compatible? */ +bool license_compatible[LICENSE_UNKNOWN+1][LICENSE_UNKNOWN]; + extern const struct license_info licenses[]; struct ccan_file; diff --git a/tools/ccanlint/tests/license_file_compat.c b/tools/ccanlint/tests/license_file_compat.c new file mode 100644 index 00000000..d1834c06 --- /dev/null +++ b/tools/ccanlint/tests/license_file_compat.c @@ -0,0 +1,64 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static void check_license_file_compat(struct manifest *m, + bool keep, + unsigned int *timeleft, + struct score *score) +{ + struct list_head *list; + + /* FIXME: Ignore unknown licenses for now. */ + if (m->license == LICENSE_UNKNOWN) { + score->pass = true; + score->score = score->total = 0; + return 0; + } + + foreach_ptr(list, &m->c_files, &m->h_files) { + struct ccan_file *f; + + list_for_each(list, f, list) { + enum license l; + + /* Check they don't have boilerplate for incompatible + * license! */ + for (l = 0; l < LICENSE_UNKNOWN; l++) { + if (!find_boilerplate(f, l)) + continue; + if (license_compatible[m->license][l]) + break; + score_file_error(score, f, 0, + "Found boilerplate for license '%s' which is incompatible with '%s'", + licenses[l].name, + licenses[m->license].name); + break; + } + } + } + + if (list_empty(&score->per_file_errors)) { + score->pass = true; + score->score = score->total; + } +} + +struct ccanlint license_file_compat = { + .key = "license_file_compat", + .name = "Source files don't contain incompatible licenses", + .check = check_license_file_compat, + .needs = "license_exists" +}; +REGISTER_TEST(license_file_compat);