Commit 2ea90b45 authored by Rusty Russell's avatar Rusty Russell

ccanlint: offer to insert license comments where they're missing.

Signed-off-by: default avatarRusty Russell <rusty@rustcorp.com.au>
parent c5a49e49
...@@ -6,75 +6,88 @@ ...@@ -6,75 +6,88 @@
const struct license_info licenses[] = { const struct license_info licenses[] = {
{ "LGPLv2+", "LGPL", { "LGPLv2+", "LGPL",
"GNU LGPL version 2 (or later)",
{ "gnu lesser general public license", { "gnu lesser general public license",
"version 2", "version 2",
"or at your option any later version" "or at your option any later version"
} }
}, },
{ "LGPLv2", "LGPL", { "LGPLv2", "LGPL",
"GNU LGPL version 2",
{ "gnu lesser general public license", { "gnu lesser general public license",
"version 2", "version 2",
NULL NULL
} }
}, },
{ "LGPLv3", "LGPL", { "LGPLv3", "LGPL",
"GNU LGPL version 3",
{ "gnu lesser general public license", { "gnu lesser general public license",
"version 3", "version 3",
NULL NULL
} }
}, },
{ "LGPL", "LGPL", { "LGPL", "LGPL",
"GNU LGPL",
{ "gnu lesser general public license", { "gnu lesser general public license",
NULL, NULL,
NULL NULL
} }
}, },
{ "GPLv2+", "GPL", { "GPLv2+", "GPL",
"GNU GPL version 2 (or later)",
{ "gnu general public license", { "gnu general public license",
"version 2", "version 2",
"or at your option any later version" "or at your option any later version"
} }
}, },
{ "GPLv2", "GPL", { "GPLv2", "GPL",
"GNU GPL version 2",
{ "gnu general public license", { "gnu general public license",
"version 2", "version 2",
NULL NULL
} }
}, },
{ "GPLv3", "GPL", { "GPLv3", "GPL",
"GNU GPL version 3 (or later)",
{ "gnu general public license", { "gnu general public license",
"version 3", "version 3",
NULL NULL
} }
}, },
{ "GPL", "GPL", { "GPL", "GPL",
"GNU GPL",
{ "gnu general public license", { "gnu general public license",
NULL, NULL,
NULL NULL
} }
}, },
{ "BSD-3CLAUSE", "BSD", { "BSD-3CLAUSE", "BSD",
"3-clause BSD license",
{ "redistributions of source code must retain", { "redistributions of source code must retain",
"redistributions in binary form must reproduce", "redistributions in binary form must reproduce",
"endorse or promote" "endorse or promote"
} }
}, },
{ "BSD-MIT", "MIT", { "BSD-MIT", "MIT",
"MIT (BSD) license",
{ "without restriction", { "without restriction",
"above copyright notice", "above copyright notice",
"without warranty" "without warranty"
} }
}, },
{ "CC0", "CC0", { "CC0", "CC0",
"CC0 license (public domain)",
{ "Waiver.", { "Waiver.",
"unconditionally waives", "unconditionally waives",
NULL NULL
} }
}, },
{ "Public domain", "Public domain", { "Public domain", "Public domain",
NULL,
{ NULL, NULL, NULL } { NULL, NULL, NULL }
}, },
{ "Unknown license", "Unknown license", { "Unknown license", "Unknown license",
NULL,
{ NULL, NULL, NULL } { NULL, NULL, NULL }
}, },
}; };
...@@ -216,3 +229,9 @@ struct doc_section *find_license_tag(const struct manifest *m) ...@@ -216,3 +229,9 @@ struct doc_section *find_license_tag(const struct manifest *m)
} }
return NULL; return NULL;
} }
const char *get_license_oneliner(const tal_t *ctx, enum license license)
{
return tal_fmt(ctx, "/* %s - see LICENSE file for details */",
licenses[license].describe);
}
#ifndef CCANLINT_LICENSES_H #ifndef CCANLINT_LICENSES_H
#define CCANLINT_LICENSES_H #define CCANLINT_LICENSES_H
#include <stdbool.h> #include <stdbool.h>
#include <ccan/tal/tal.h>
enum license { enum license {
LICENSE_LGPLv2_PLUS, LICENSE_LGPLv2_PLUS,
...@@ -23,6 +24,7 @@ enum license { ...@@ -23,6 +24,7 @@ enum license {
struct license_info { struct license_info {
const char *name; const char *name;
const char *shortname; const char *shortname;
const char *describe;
/* Edit distance is expensive, and this works quite well. */ /* Edit distance is expensive, and this works quite well. */
const char *clause[NUM_CLAUSES]; const char *clause[NUM_CLAUSES];
}; };
...@@ -41,4 +43,6 @@ enum license which_license(struct doc_section *d); ...@@ -41,4 +43,6 @@ enum license which_license(struct doc_section *d);
struct manifest; struct manifest;
struct doc_section *find_license_tag(const struct manifest *m); struct doc_section *find_license_tag(const struct manifest *m);
const char *get_license_oneliner(const tal_t *ctx, enum license license);
#endif /* CCANLINT_LICENSES_H */ #endif /* CCANLINT_LICENSES_H */
...@@ -57,10 +57,49 @@ static void check_license_comment(struct manifest *m, ...@@ -57,10 +57,49 @@ static void check_license_comment(struct manifest *m,
} }
} }
static void add_license_comment(struct manifest *m, struct score *score)
{
struct file_error *e;
const char *license_desc = get_license_oneliner(score, m->license);
char *files = tal_strdup(score, ""), *q;
list_for_each(&score->per_file_errors, e, list)
tal_append_fmt(&files, " %s\n", e->file->name);
q = tal_fmt(score, "The following files don't have a comment:\n%s\n"
"Should I prepend '%s'?", files, license_desc);
if (!ask(q))
return;
list_for_each(&score->per_file_errors, e, list) {
char *tmpname;
FILE *out;
unsigned int i;
tmpname = temp_file(score, ".licensed", e->file->name);
out = fopen(tmpname, "w");
if (!out)
err(1, "Opening %s", tmpname);
if (fprintf(out, "%s\n", license_desc) < 0)
err(1, "Writing %s", tmpname);
for (i = 0; e->file->lines[i]; i++)
if (fprintf(out, "%s\n", e->file->lines[i]) < 0)
err(1, "Writing %s", tmpname);
if (fclose(out) != 0)
err(1, "Closing %s", tmpname);
if (!move_file(tmpname, e->file->fullname))
err(1, "Moving %s to %s", tmpname, e->file->fullname);
}
}
struct ccanlint license_comment = { struct ccanlint license_comment = {
.key = "license_comment", .key = "license_comment",
.name = "Source and header files refer to LICENSE", .name = "Source and header files refer to LICENSE",
.check = check_license_comment, .check = check_license_comment,
.handle = add_license_comment,
.needs = "license_exists" .needs = "license_exists"
}; };
REGISTER_TEST(license_comment); REGISTER_TEST(license_comment);
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