[v4] devtools: add new SPDX license compliance checker
Checks
Commit Message
Simple script to look for drivers and scripts that
are missing requires SPDX header.
Update the contribution guidelines to indicate that SPDX license
identfier is required for this project.
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
v4 - add MAINTAINERS entry
update coding style document
change name of script
MAINTAINERS | 1 +
devtools/check-spdx-tag.sh | 77 ++++++++++++++++++++++++
doc/guides/contributing/coding_style.rst | 9 ++-
3 files changed, 85 insertions(+), 2 deletions(-)
create mode 100755 devtools/check-spdx-tag.sh
Comments
On Mon, 24 Feb 2020 13:01:30 -0800
Stephen Hemminger <stephen@networkplumber.org> wrote:
> Simple script to look for drivers and scripts that
> are missing requires SPDX header.
>
> Update the contribution guidelines to indicate that SPDX license
> identfier is required for this project.
>
> Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
> ---
> v4 - add MAINTAINERS entry
> update coding style document
> change name of script
>
> MAINTAINERS | 1 +
> devtools/check-spdx-tag.sh | 77 ++++++++++++++++++++++++
> doc/guides/contributing/coding_style.rst | 9 ++-
> 3 files changed, 85 insertions(+), 2 deletions(-)
> create mode 100755 devtools/check-spdx-tag.sh
Still waiting for this script all requested changes were done months ago.
Current output is:
$ ./devtools/check-spdx-tag.sh -v
Files without SPDX License
--------------------------
Files with redundant license text
---------------------------------
app/test/test_timer_racecond.c
lib/librte_ethdev/rte_ethdev_pci.h
lib/librte_ethdev/rte_ethdev_vdev.h
total: 0 errors, 3 warnings
On Mon, 24 Feb 2020 13:01:30 -0800
Stephen Hemminger <stephen@networkplumber.org> wrote:
> Simple script to look for drivers and scripts that
> are missing requires SPDX header.
>
> Update the contribution guidelines to indicate that SPDX license
> identfier is required for this project.
>
> Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
> ---
> v4 - add MAINTAINERS entry
> update coding style document
> change name of script
>
> MAINTAINERS | 1 +
> devtools/check-spdx-tag.sh | 77 ++++++++++++++++++++++++
> doc/guides/contributing/coding_style.rst | 9 ++-
> 3 files changed, 85 insertions(+), 2 deletions(-)
> create mode 100755 devtools/check-spdx-tag.sh
>
Going through the patch backlog.
Why is this not merged yet?
Why is not in DPDK 20.05?
11/06/2020 20:46, Stephen Hemminger:
> On Mon, 24 Feb 2020 13:01:30 -0800
> Stephen Hemminger <stephen@networkplumber.org> wrote:
>
> > Simple script to look for drivers and scripts that
> > are missing requires SPDX header.
> >
> > Update the contribution guidelines to indicate that SPDX license
> > identfier is required for this project.
> >
> > Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
>
> Going through the patch backlog.
>
> Why is this not merged yet?
> Why is not in DPDK 20.05?
I would like to see some reviews on such patch
which looks like a policy.
24/02/2020 22:01, Stephen Hemminger:
> +tmpfile=$(mktemp)
Please check how other temp files are created in other scripts
for consitency.
> + git grep -L SPDX-License-Identifier -- \
> + ':^.git*' ':^.ci/*' ':^.travis.yml' \
> + ':^README' ':^MAINTAINERS' ':^VERSION' ':^ABI_VERSION' \
> + ':^*/Kbuild' ':^*/README' \
> + ':^license/' ':^doc/' ':^config/' ':^buildtools/' \
I think doc/ should be part of the license check,
same for buildtools/.
> + ':^*.cocci' ':^*.abignore' \
> + ':^*.def' ':^*.map' ':^*.ini' ':^*.data' ':^*.cfg' ':^*.txt' \
> + > $tmpfile
> +
> + errors=0
> + while read -r line
> + do $quiet || echo $line
> + errors=$((errors + 1))
I'm surprised this works for you.
In general, "while" creates a subshell which makes impossible
updating a variable.
I recommend using "for" with IFS=$'\n'.
> + done < $tmpfile
> +}
> +
> +check_boilerplate() {
> + if $verbose ; then
> + echo
> + echo "Files with redundant license text"
> + echo "---------------------------------"
> + fi
> +
> + git grep -l Redistribution -- \
> + ':^license/' ':^/devtools/check-spdx-tag.sh' |
> + while read line
> + do $quiet || echo $line
> + warnings=$((warnings + 1))
> + done
Same comment about "while" subshell.
> +
> + warnings=0
> + while read -r line
> + do $quiet || echo $line
> + warnings=$((errors + 1))
Here too
> + done < $tmpfile
> +}
[...]
> +Each file must begin with a special comment containing the
> +`Software Package Data Exchange (SPDX) License Identfier <https://spdx.org/using-spdx-license-identifier>`_.
Typo: Identifier
> +
> +Generally this is the BSD License, except for code granted special exceptions.
Is a verb missing?
> +The SPDX licences identifier is sufficient, a file should not contain
> +an additional text version of the license (boilerplate).
Hi Thomas, Stephen,
On 11/06/20 23:39 +0200, Thomas Monjalon wrote:
> 24/02/2020 22:01, Stephen Hemminger:
> > +tmpfile=$(mktemp)
>
> Please check how other temp files are created in other scripts
> for consitency.
>
> > + git grep -L SPDX-License-Identifier -- \
> > + ':^.git*' ':^.ci/*' ':^.travis.yml' \
> > + ':^README' ':^MAINTAINERS' ':^VERSION' ':^ABI_VERSION' \
> > + ':^*/Kbuild' ':^*/README' \
> > + ':^license/' ':^doc/' ':^config/' ':^buildtools/' \
>
> I think doc/ should be part of the license check,
> same for buildtools/.
>
> > + ':^*.cocci' ':^*.abignore' \
> > + ':^*.def' ':^*.map' ':^*.ini' ':^*.data' ':^*.cfg' ':^*.txt' \
> > + > $tmpfile
> > +
> > + errors=0
> > + while read -r line
> > + do $quiet || echo $line
> > + errors=$((errors + 1))
>
> I'm surprised this works for you.
> In general, "while" creates a subshell which makes impossible
> updating a variable.
> I recommend using "for" with IFS=$'\n'.
>
No it should work, while will only spawn a subshell if you use a pipe with it.
Ex:
err=0; while true; do err=$((err + 1)); done # $err changes
err=0; yes | while read -r y; do err=$((err + 1)); done # $err is always 0
Using for could be an issue, as you are then limited by the number of
parameters allowed. Additionally, the script is written for POSIX shell,
using $'\n' is forbidden and the POSIX equivalent is very ugly:
IFS="$(printf '%b_' '\n')"; IFS="${IFS%_}" # protect trailing \n
> > + done < $tmpfile
> > +}
> > +
> > +check_boilerplate() {
> > + if $verbose ; then
> > + echo
> > + echo "Files with redundant license text"
> > + echo "---------------------------------"
> > + fi
> > +
> > + git grep -l Redistribution -- \
> > + ':^license/' ':^/devtools/check-spdx-tag.sh' |
> > + while read line
Missing a -r to read here: https://www.shellcheck.net/wiki/SC2162
Generally, best to use shellcheck when writing a script, especially if
using /bin/sh.
> > + do $quiet || echo $line
> > + warnings=$((warnings + 1))
> > + done
>
> Same comment about "while" subshell.
>
> > +
> > + warnings=0
> > + while read -r line
> > + do $quiet || echo $line
> > + warnings=$((errors + 1))
>
> Here too
>
> > + done < $tmpfile
> > +}
>
> [...]
> > +Each file must begin with a special comment containing the
> > +`Software Package Data Exchange (SPDX) License Identfier <https://spdx.org/using-spdx-license-identifier>`_.
>
> Typo: Identifier
>
> > +
> > +Generally this is the BSD License, except for code granted special exceptions.
>
> Is a verb missing?
>
> > +The SPDX licences identifier is sufficient, a file should not contain
> > +an additional text version of the license (boilerplate).
>
>
>
On 24/02/20 13:01 -0800, Stephen Hemminger wrote:
> Simple script to look for drivers and scripts that
> are missing requires SPDX header.
>
> Update the contribution guidelines to indicate that SPDX license
> identfier is required for this project.
>
> Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
> ---
> v4 - add MAINTAINERS entry
> update coding style document
> change name of script
>
> MAINTAINERS | 1 +
> devtools/check-spdx-tag.sh | 77 ++++++++++++++++++++++++
> doc/guides/contributing/coding_style.rst | 9 ++-
> 3 files changed, 85 insertions(+), 2 deletions(-)
> create mode 100755 devtools/check-spdx-tag.sh
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 3d5e8d1104b2..6b0e042c5fbb 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -96,6 +96,7 @@ F: devtools/check-maintainers.sh
> F: devtools/check-forbidden-tokens.awk
> F: devtools/check-git-log.sh
> F: devtools/check-includes.sh
> +F: devtools/check-spdx-tag.sh
> F: devtools/check-symbol-maps.sh
> F: devtools/checkpatches.sh
> F: devtools/get-maintainer.sh
> diff --git a/devtools/check-spdx-tag.sh b/devtools/check-spdx-tag.sh
> new file mode 100755
> index 000000000000..b1b8cdba4e4e
> --- /dev/null
> +++ b/devtools/check-spdx-tag.sh
> @@ -0,0 +1,77 @@
> +#! /bin/sh
> +# SPDX-License-Identifier: BSD-3-Clause
> +# Copyright (c) 2019 Microsoft Corporation
> +#
> +# Produce a list of files with incorrect license tags
> +
> +print_usage () {
> + echo "usage: $(basename $0) [-q] [-v]"
> + exit 1
> +}
> +
> +check_spdx() {
> + if $verbose; then
> + echo "Files without SPDX License"
> + echo "--------------------------"
> + fi
> + git grep -L SPDX-License-Identifier -- \
> + ':^.git*' ':^.ci/*' ':^.travis.yml' \
> + ':^README' ':^MAINTAINERS' ':^VERSION' ':^ABI_VERSION' \
> + ':^*/Kbuild' ':^*/README' \
> + ':^license/' ':^doc/' ':^config/' ':^buildtools/' \
> + ':^*.cocci' ':^*.abignore' \
> + ':^*.def' ':^*.map' ':^*.ini' ':^*.data' ':^*.cfg' ':^*.txt' \
> + > $tmpfile
I find it easier to maintain an exclude list by setting a variable and
generating the relevant parameters:
excludes='.git* .ci/* .travis.yml */Kbuild */README'
exclude_opt=""
set -f
for pattern in $excludes; do
exclude_opt="$exclude_opt ':^${pattern}'"
done
set +f
printf "\"%s\"\n" "$exclude_opt"
However I recognize that means dealing with contrarian globbing issues in shells,
so it comes at a price. But I find changing the exclude list much easier that way.
> +
> + errors=0
> + while read -r line
> + do $quiet || echo $line
> + errors=$((errors + 1))
> + done < $tmpfile
> +}
> +
> +check_boilerplate() {
> + if $verbose ; then
> + echo
> + echo "Files with redundant license text"
> + echo "---------------------------------"
> + fi
> +
> + git grep -l Redistribution -- \
> + ':^license/' ':^/devtools/check-spdx-tag.sh' |
> + while read line
> + do $quiet || echo $line
> + warnings=$((warnings + 1))
> + done
> +
> + warnings=0
> + while read -r line
> + do $quiet || echo $line
> + warnings=$((errors + 1))
> + done < $tmpfile
> +}
> +
> +quiet=false
> +verbose=false
> +
> +while getopts qvh ARG ; do
> + case $ARG in
> + q ) quiet=true ;;
> + v ) verbose=true ;;
> + h ) print_usage ; exit 0 ;;
> + ? ) print_usage ; exit 1 ;;
> + esac
> +done
> +shift $(($OPTIND - 1))
> +
> +tmpfile=$(mktemp)
> +trap 'rm -f -- "$tmpfile"' INT TERM HUP EXIT
> +
> +check_spdx
> +$quiet || echo
> +
> +check_boilerplate
> +
> +$quiet || echo
> +echo "total: $errors errors, $warnings warnings"
> +exit $errors
> diff --git a/doc/guides/contributing/coding_style.rst b/doc/guides/contributing/coding_style.rst
> index 841ef6d5c829..04626667dc18 100644
> --- a/doc/guides/contributing/coding_style.rst
> +++ b/doc/guides/contributing/coding_style.rst
> @@ -54,8 +54,13 @@ To document a public API, a doxygen-like format must be used: refer to :ref:`dox
> License Header
> ~~~~~~~~~~~~~~
>
> -Each file should begin with a special comment containing the appropriate copyright and license for the file.
> -Generally this is the BSD License, except for code for Linux Kernel modules.
> +Each file must begin with a special comment containing the
> +`Software Package Data Exchange (SPDX) License Identfier <https://spdx.org/using-spdx-license-identifier>`_.
> +
> +Generally this is the BSD License, except for code granted special exceptions.
> +The SPDX licences identifier is sufficient, a file should not contain
> +an additional text version of the license (boilerplate).
> +
> After any copyright header, a blank line should be left before any other contents, e.g. include statements in a C file.
>
> C Preprocessor Directives
> --
> 2.20.1
>
On Thu, 11 Jun 2020 23:39:55 +0200
Thomas Monjalon <thomas@monjalon.net> wrote:
> 24/02/2020 22:01, Stephen Hemminger:
> > +tmpfile=$(mktemp)
>
> Please check how other temp files are created in other scripts
> for consitency.
>
> > + git grep -L SPDX-License-Identifier -- \
> > + ':^.git*' ':^.ci/*' ':^.travis.yml' \
> > + ':^README' ':^MAINTAINERS' ':^VERSION' ':^ABI_VERSION' \
> > + ':^*/Kbuild' ':^*/README' \
> > + ':^license/' ':^doc/' ':^config/' ':^buildtools/' \
>
> I think doc/ should be part of the license check,
> same for buildtools/.
>
> > + ':^*.cocci' ':^*.abignore' \
> > + ':^*.def' ':^*.map' ':^*.ini' ':^*.data' ':^*.cfg' ':^*.txt' \
> > + > $tmpfile
> > +
> > + errors=0
> > + while read -r line
> > + do $quiet || echo $line
> > + errors=$((errors + 1))
>
> I'm surprised this works for you.
> In general, "while" creates a subshell which makes impossible
> updating a variable.
> I recommend using "for" with IFS=$'\n'.
>
> > + done < $tmpfile
> > +}
> > +
> > +check_boilerplate() {
> > + if $verbose ; then
> > + echo
> > + echo "Files with redundant license text"
> > + echo "---------------------------------"
> > + fi
> > +
> > + git grep -l Redistribution -- \
> > + ':^license/' ':^/devtools/check-spdx-tag.sh' |
> > + while read line
> > + do $quiet || echo $line
> > + warnings=$((warnings + 1))
> > + done
>
> Same comment about "while" subshell.
>
> > +
> > + warnings=0
> > + while read -r line
> > + do $quiet || echo $line
> > + warnings=$((errors + 1))
>
> Here too
>
> > + done < $tmpfile
> > +}
>
> [...]
> > +Each file must begin with a special comment containing the
> > +`Software Package Data Exchange (SPDX) License Identfier <https://spdx.org/using-spdx-license-identifier>`_.
>
> Typo: Identifier
>
> > +
> > +Generally this is the BSD License, except for code granted special exceptions.
>
> Is a verb missing?
>
> > +The SPDX licences identifier is sufficient, a file should not contain
> > +an additional text version of the license (boilerplate).
Thanks for the feedback.
Text processing is simpler in python, will rewrite in next version?
12/06/2020 16:53, Stephen Hemminger:
> On Thu, 11 Jun 2020 23:39:55 +0200
> Thomas Monjalon <thomas@monjalon.net> wrote:
>
> > 24/02/2020 22:01, Stephen Hemminger:
> > > +tmpfile=$(mktemp)
> >
> > Please check how other temp files are created in other scripts
> > for consitency.
> >
> > > + git grep -L SPDX-License-Identifier -- \
> > > + ':^.git*' ':^.ci/*' ':^.travis.yml' \
> > > + ':^README' ':^MAINTAINERS' ':^VERSION' ':^ABI_VERSION' \
> > > + ':^*/Kbuild' ':^*/README' \
> > > + ':^license/' ':^doc/' ':^config/' ':^buildtools/' \
> >
> > I think doc/ should be part of the license check,
> > same for buildtools/.
> >
> > > + ':^*.cocci' ':^*.abignore' \
> > > + ':^*.def' ':^*.map' ':^*.ini' ':^*.data' ':^*.cfg' ':^*.txt' \
> > > + > $tmpfile
> > > +
> > > + errors=0
> > > + while read -r line
> > > + do $quiet || echo $line
> > > + errors=$((errors + 1))
> >
> > I'm surprised this works for you.
> > In general, "while" creates a subshell which makes impossible
> > updating a variable.
> > I recommend using "for" with IFS=$'\n'.
> >
> > > + done < $tmpfile
> > > +}
> > > +
> > > +check_boilerplate() {
> > > + if $verbose ; then
> > > + echo
> > > + echo "Files with redundant license text"
> > > + echo "---------------------------------"
> > > + fi
> > > +
> > > + git grep -l Redistribution -- \
> > > + ':^license/' ':^/devtools/check-spdx-tag.sh' |
> > > + while read line
> > > + do $quiet || echo $line
> > > + warnings=$((warnings + 1))
> > > + done
> >
> > Same comment about "while" subshell.
> >
> > > +
> > > + warnings=0
> > > + while read -r line
> > > + do $quiet || echo $line
> > > + warnings=$((errors + 1))
> >
> > Here too
> >
> > > + done < $tmpfile
> > > +}
> >
> > [...]
> > > +Each file must begin with a special comment containing the
> > > +`Software Package Data Exchange (SPDX) License Identfier <https://spdx.org/using-spdx-license-identifier>`_.
> >
> > Typo: Identifier
> >
> > > +
> > > +Generally this is the BSD License, except for code granted special exceptions.
> >
> > Is a verb missing?
> >
> > > +The SPDX licences identifier is sufficient, a file should not contain
> > > +an additional text version of the license (boilerplate).
>
> Thanks for the feedback.
> Text processing is simpler in python, will rewrite in next version?
I don't see a need for rewrite.
I think addressing the comments is simpler.
On Fri, 12 Jun 2020 11:05:27 +0200
Gaëtan Rivet <grive@u256.net> wrote:
> On 24/02/20 13:01 -0800, Stephen Hemminger wrote:
> > Simple script to look for drivers and scripts that
> > are missing requires SPDX header.
> >
> > Update the contribution guidelines to indicate that SPDX license
> > identfier is required for this project.
> >
> > Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
> > ---
> > v4 - add MAINTAINERS entry
> > update coding style document
> > change name of script
> >
> > MAINTAINERS | 1 +
> > devtools/check-spdx-tag.sh | 77 ++++++++++++++++++++++++
> > doc/guides/contributing/coding_style.rst | 9 ++-
> > 3 files changed, 85 insertions(+), 2 deletions(-)
> > create mode 100755 devtools/check-spdx-tag.sh
> >
> > diff --git a/MAINTAINERS b/MAINTAINERS
> > index 3d5e8d1104b2..6b0e042c5fbb 100644
> > --- a/MAINTAINERS
> > +++ b/MAINTAINERS
> > @@ -96,6 +96,7 @@ F: devtools/check-maintainers.sh
> > F: devtools/check-forbidden-tokens.awk
> > F: devtools/check-git-log.sh
> > F: devtools/check-includes.sh
> > +F: devtools/check-spdx-tag.sh
> > F: devtools/check-symbol-maps.sh
> > F: devtools/checkpatches.sh
> > F: devtools/get-maintainer.sh
> > diff --git a/devtools/check-spdx-tag.sh b/devtools/check-spdx-tag.sh
> > new file mode 100755
> > index 000000000000..b1b8cdba4e4e
> > --- /dev/null
> > +++ b/devtools/check-spdx-tag.sh
> > @@ -0,0 +1,77 @@
> > +#! /bin/sh
> > +# SPDX-License-Identifier: BSD-3-Clause
> > +# Copyright (c) 2019 Microsoft Corporation
> > +#
> > +# Produce a list of files with incorrect license tags
> > +
> > +print_usage () {
> > + echo "usage: $(basename $0) [-q] [-v]"
> > + exit 1
> > +}
> > +
> > +check_spdx() {
> > + if $verbose; then
> > + echo "Files without SPDX License"
> > + echo "--------------------------"
> > + fi
> > + git grep -L SPDX-License-Identifier -- \
> > + ':^.git*' ':^.ci/*' ':^.travis.yml' \
> > + ':^README' ':^MAINTAINERS' ':^VERSION' ':^ABI_VERSION' \
> > + ':^*/Kbuild' ':^*/README' \
> > + ':^license/' ':^doc/' ':^config/' ':^buildtools/' \
> > + ':^*.cocci' ':^*.abignore' \
> > + ':^*.def' ':^*.map' ':^*.ini' ':^*.data' ':^*.cfg' ':^*.txt' \
> > + > $tmpfile
>
> I find it easier to maintain an exclude list by setting a variable and
> generating the relevant parameters:
>
> excludes='.git* .ci/* .travis.yml */Kbuild */README'
> exclude_opt=""
> set -f
> for pattern in $excludes; do
> exclude_opt="$exclude_opt ':^${pattern}'"
> done
> set +f
> printf "\"%s\"\n" "$exclude_opt"
>
> However I recognize that means dealing with contrarian globbing issues in shells,
> so it comes at a price. But I find changing the exclude list much easier that way.
This is no easier to maintain. Doing more string stuff in shell
is not worth it. If gets to be too much trouble, will consider moving
to python3.
@@ -96,6 +96,7 @@ F: devtools/check-maintainers.sh
F: devtools/check-forbidden-tokens.awk
F: devtools/check-git-log.sh
F: devtools/check-includes.sh
+F: devtools/check-spdx-tag.sh
F: devtools/check-symbol-maps.sh
F: devtools/checkpatches.sh
F: devtools/get-maintainer.sh
new file mode 100755
@@ -0,0 +1,77 @@
+#! /bin/sh
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright (c) 2019 Microsoft Corporation
+#
+# Produce a list of files with incorrect license tags
+
+print_usage () {
+ echo "usage: $(basename $0) [-q] [-v]"
+ exit 1
+}
+
+check_spdx() {
+ if $verbose; then
+ echo "Files without SPDX License"
+ echo "--------------------------"
+ fi
+ git grep -L SPDX-License-Identifier -- \
+ ':^.git*' ':^.ci/*' ':^.travis.yml' \
+ ':^README' ':^MAINTAINERS' ':^VERSION' ':^ABI_VERSION' \
+ ':^*/Kbuild' ':^*/README' \
+ ':^license/' ':^doc/' ':^config/' ':^buildtools/' \
+ ':^*.cocci' ':^*.abignore' \
+ ':^*.def' ':^*.map' ':^*.ini' ':^*.data' ':^*.cfg' ':^*.txt' \
+ > $tmpfile
+
+ errors=0
+ while read -r line
+ do $quiet || echo $line
+ errors=$((errors + 1))
+ done < $tmpfile
+}
+
+check_boilerplate() {
+ if $verbose ; then
+ echo
+ echo "Files with redundant license text"
+ echo "---------------------------------"
+ fi
+
+ git grep -l Redistribution -- \
+ ':^license/' ':^/devtools/check-spdx-tag.sh' |
+ while read line
+ do $quiet || echo $line
+ warnings=$((warnings + 1))
+ done
+
+ warnings=0
+ while read -r line
+ do $quiet || echo $line
+ warnings=$((errors + 1))
+ done < $tmpfile
+}
+
+quiet=false
+verbose=false
+
+while getopts qvh ARG ; do
+ case $ARG in
+ q ) quiet=true ;;
+ v ) verbose=true ;;
+ h ) print_usage ; exit 0 ;;
+ ? ) print_usage ; exit 1 ;;
+ esac
+done
+shift $(($OPTIND - 1))
+
+tmpfile=$(mktemp)
+trap 'rm -f -- "$tmpfile"' INT TERM HUP EXIT
+
+check_spdx
+$quiet || echo
+
+check_boilerplate
+
+$quiet || echo
+echo "total: $errors errors, $warnings warnings"
+exit $errors
@@ -54,8 +54,13 @@ To document a public API, a doxygen-like format must be used: refer to :ref:`dox
License Header
~~~~~~~~~~~~~~
-Each file should begin with a special comment containing the appropriate copyright and license for the file.
-Generally this is the BSD License, except for code for Linux Kernel modules.
+Each file must begin with a special comment containing the
+`Software Package Data Exchange (SPDX) License Identfier <https://spdx.org/using-spdx-license-identifier>`_.
+
+Generally this is the BSD License, except for code granted special exceptions.
+The SPDX licences identifier is sufficient, a file should not contain
+an additional text version of the license (boilerplate).
+
After any copyright header, a blank line should be left before any other contents, e.g. include statements in a C file.
C Preprocessor Directives