Skip to content

Commit

Permalink
Add a lint check for SPDX licenses
Browse files Browse the repository at this point in the history
and update the documentation.
Supersedes and closes #2224
  • Loading branch information
AltGr committed Sep 3, 2019
1 parent b963ef2 commit 97c22c6
Show file tree
Hide file tree
Showing 5 changed files with 506 additions and 2 deletions.
4 changes: 2 additions & 2 deletions doc/pages/Manual.md
Expand Up @@ -787,8 +787,8 @@ files.
a list of strings listing the original authors of the software.

- <a id="opamfield-license">`license: [ <string> ... ]`</a>:
the abbreviated name(s) of the license(s) under which the source software is
available.
The SPDX ID of the license(s) under which the source software is available
(see http://spdx.org/licenses/).

- <a id="opamfield-homepage">`homepage: [ <string> ... ]`</a>,
<a id="opamfield-doc">`doc: [ <string> ... ]`</a>,
Expand Down
30 changes: 30 additions & 0 deletions src/state/dune
Expand Up @@ -14,3 +14,33 @@
(targets opamScript.ml)
(deps ../../shell/crunch.ml (glob_files shellscripts/*.*sh))
(action (with-stdout-to %{targets} (run ocaml %{deps}))))


;; These rules are here to document and for easy (re-)generation of the module,
;; but relying on the checked-in file should be OK (we don't want to rely on
;; either `jq` or a network download). Hence the `(mode fallback)`.
(rule
(targets opamSpdxList.ml)
(mode fallback)
(action (with-stdout-to %{targets}
(progn
(echo "(* THIS FILE IS GENERATED. See dune file *)\n\n")
(echo "open OpamCompat\n")
(echo "let licenses = OpamStd.String.Set.of_list @@ List.map String.lowercase_ascii @@ [\n")
(cat spdx-license-list)
(echo "]\n")
(echo "let exceptions = OpamStd.String.Set.of_list @@ List.map String.lowercase_ascii @@ [\n")
(cat spdx-license-exn-list)
(echo "]\n")))))
(rule
(targets spdx-license-list)
(action (with-stdout-to %{targets}
(system
"curl https://raw.githubusercontent.com/spdx/license-list-data/master/json/licenses.json |
jq -rc '.licenses | map(\" \\\"\" + .licenseId + \"\\\";\") | join(\"\\n\")'"))))
(rule
(targets spdx-license-exn-list)
(action (with-stdout-to %{targets}
(system
"curl https://raw.githubusercontent.com/spdx/license-list-data/master/json/exceptions.json |
jq -rc '.exceptions | map(\" \\\"\" + .licenseExceptionId + \"\\\";\") | join(\"\\n\")'"))))
18 changes: 18 additions & 0 deletions src/state/opamFileTools.ml
Expand Up @@ -16,6 +16,17 @@ let log fmt = OpamConsole.log "opam-file" fmt

open OpamFile.OPAM

let is_valid_license_id s =
let memplus s =
let s = OpamStd.String.remove_suffix ~suffix:"+" s in
OpamStd.String.Set.mem s OpamSpdxList.licenses
in
match OpamStd.String.split (String.lowercase_ascii s) ' ' with
| [s] -> memplus s
| [s; "with"; e] ->
memplus s && OpamStd.String.Set.mem e OpamSpdxList.exceptions
| _ -> false

(** manipulation utilities *)

let names_of_formula flag f =
Expand Down Expand Up @@ -686,6 +697,13 @@ let t_lint ?check_extra_files ?(check_upstream=false) ?(all=false) t =
cond 61 `Warning
"`with-test` variable in `run-test` is out of scope, it will be ignored"
with_test);
(let bad_licenses =
List.filter (fun s -> not (is_valid_license_id s)) t.license
in
cond 62 `Warning
"License doesn't adhere to the SPDX standard, see https://spdx.org/licenses/"
~detail:bad_licenses
(bad_licenses <> []));
]
in
format_errors @
Expand Down

0 comments on commit 97c22c6

Please sign in to comment.