diff mbox series

[2/3] scripts: validate SPDX license choices

Message ID 20241007154548.1144961-3-berrange@redhat.com (mailing list archive)
State New, archived
Headers show
Series scripts: mandate use of SPDX-License-Identifier tags in new files | expand

Commit Message

Daniel P. Berrangé Oct. 7, 2024, 3:45 p.m. UTC
We expect all new code to be contributed with the "GPL-2.0-or-later"
license tag. Divergance is permitted if the new file is derived from
pre-existing code under a different license, whether from elsewhere
in QEMU codebase, or outside.

Issue a warning if the declared license is not "GPL-2.0-or-later",
and an error if the license is not one of the handful of the
expected licenses to prevent unintended proliferation.

Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
 scripts/checkpatch.pl | 66 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 66 insertions(+)

Comments

Brian Cain Oct. 7, 2024, 4:19 p.m. UTC | #1
On 10/7/2024 10:45 AM, Daniel P. Berrangé wrote:
> We expect all new code to be contributed with the "GPL-2.0-or-later"
> license tag. Divergance is permitted if the new file is derived from
> pre-existing code under a different license, whether from elsewhere
> in QEMU codebase, or outside.
>
> Issue a warning if the declared license is not "GPL-2.0-or-later",
> and an error if the license is not one of the handful of the
> expected licenses to prevent unintended proliferation.
>
> Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
> ---
>   scripts/checkpatch.pl | 66 +++++++++++++++++++++++++++++++++++++++++++
>   1 file changed, 66 insertions(+)
>
> diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
> index cc266abdcd..cd1ed90f4c 100755
> --- a/scripts/checkpatch.pl
> +++ b/scripts/checkpatch.pl
> @@ -1353,6 +1353,67 @@ sub checkfilename {
>   	}
>   }
>   
> +sub checkspdx {
> +    my ($file, $expr) = @_;
> +
> +    # Imported Linux headers probably have SPDX tags, but if they
> +    # don't we're not requiring contributors to fix this
> +    if ($file =~ m,include/standard-headers, ||
> +	$file =~ m,linux-headers,) {
> +	return;
> +    }
> +
> +    my $origexpr = $expr;
> +
> +    # Flatten sub-expressions
> +    $expr =~ s/\(|\)/ /g;
> +    $expr =~ s/OR|AND/ /g;
> +
> +    # Merge WITH exceptions to the license
> +    $expr =~ s/\s+WITH\s+/-WITH-/g;
> +
> +    # Cull more leading/trailing whitespace
> +    $expr =~ s/^\s*//g;
> +    $expr =~ s/\s*$//g;
> +
> +    my @bits = split / +/, $expr;
> +
> +    my $prefer = "GPL-2.0-or-later";
> +    my @valid = qw(
> +	LGPL-2.0-or-later
> +	LGPL-2.1-or-later
> +	GPL-2.0-only
> +	LGPL-2.0-only
> +	LGPL-2.0-only
> +	BSD-2-Clause
> +	BSD-3-Clause
> +	MIT
> +	);
> +
> +    my $nonpreferred = 0;
> +    my @unknown = ();
> +    foreach my $bit (@bits) {
> +	if ($bit eq $prefer) {
> +	    next;
> +	}
> +	if (grep /^$bit$/, @valid) {
> +	    $nonpreferred = 1;
> +	} else {
> +	    push @unknown, $bit;
> +	}
> +    }
> +    if (@unknown) {
> +	ERROR("Saw unacceptable licenses '" . join(',', @unknown) .
> +	      "', valid choices for QEMU are:\n" . join("\n", $prefer, @valid));
> +    }
> +
> +    if ($nonpreferred) {
> +	WARN("Saw acceptable license '$origexpr' but note '$prefer' is preferred " .
> +	     "for new files unless the code is derived from a source with an" .
> +	     "existed declared license that must be followed.");

Is it not preferred to contribute code under the BSD-3-clause? Based on 
other items in the project, I was expecting we could make contributions 
for hexagon w/BSD.  But those are exceptional cases and not to be 
followed in the general case?


> +    }
> +}
> +
>   sub process {
>   	my $filename = shift;
>   
> @@ -1641,6 +1702,11 @@ sub process {
>   		    }
>   		}
>   
> +# Check SPDX-License-Identifier references a permitted license
> +		if ($rawline =~ m,SPDX-License-Identifier: (.*?)(\*/)?\s*$,) {
> +		    &checkspdx($realfile, $1);
> +		}
> +
>   # Check for wrappage within a valid hunk of the file
>   		if ($realcnt != 0 && $line !~ m{^(?:\+|-| |\\ No newline|$)}) {
>   			ERROR("patch seems to be corrupt (line wrapped?)\n" .
Daniel P. Berrangé Oct. 7, 2024, 4:49 p.m. UTC | #2
On Mon, Oct 07, 2024 at 11:19:15AM -0500, Brian Cain wrote:
> 
> On 10/7/2024 10:45 AM, Daniel P. Berrangé wrote:
> > We expect all new code to be contributed with the "GPL-2.0-or-later"
> > license tag. Divergance is permitted if the new file is derived from
> > pre-existing code under a different license, whether from elsewhere
> > in QEMU codebase, or outside.
> > 
> > Issue a warning if the declared license is not "GPL-2.0-or-later",
> > and an error if the license is not one of the handful of the
> > expected licenses to prevent unintended proliferation.
> > 
> > Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
> > ---
> >   scripts/checkpatch.pl | 66 +++++++++++++++++++++++++++++++++++++++++++
> >   1 file changed, 66 insertions(+)
> > 
> > diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
> > index cc266abdcd..cd1ed90f4c 100755
> > --- a/scripts/checkpatch.pl
> > +++ b/scripts/checkpatch.pl
> > @@ -1353,6 +1353,67 @@ sub checkfilename {
> >   	}
> >   }
> > +sub checkspdx {
> > +    my ($file, $expr) = @_;
> > +
> > +    # Imported Linux headers probably have SPDX tags, but if they
> > +    # don't we're not requiring contributors to fix this
> > +    if ($file =~ m,include/standard-headers, ||
> > +	$file =~ m,linux-headers,) {
> > +	return;
> > +    }
> > +
> > +    my $origexpr = $expr;
> > +
> > +    # Flatten sub-expressions
> > +    $expr =~ s/\(|\)/ /g;
> > +    $expr =~ s/OR|AND/ /g;
> > +
> > +    # Merge WITH exceptions to the license
> > +    $expr =~ s/\s+WITH\s+/-WITH-/g;
> > +
> > +    # Cull more leading/trailing whitespace
> > +    $expr =~ s/^\s*//g;
> > +    $expr =~ s/\s*$//g;
> > +
> > +    my @bits = split / +/, $expr;
> > +
> > +    my $prefer = "GPL-2.0-or-later";
> > +    my @valid = qw(
> > +	LGPL-2.0-or-later
> > +	LGPL-2.1-or-later
> > +	GPL-2.0-only
> > +	LGPL-2.0-only
> > +	LGPL-2.0-only
> > +	BSD-2-Clause
> > +	BSD-3-Clause
> > +	MIT
> > +	);
> > +
> > +    my $nonpreferred = 0;
> > +    my @unknown = ();
> > +    foreach my $bit (@bits) {
> > +	if ($bit eq $prefer) {
> > +	    next;
> > +	}
> > +	if (grep /^$bit$/, @valid) {
> > +	    $nonpreferred = 1;
> > +	} else {
> > +	    push @unknown, $bit;
> > +	}
> > +    }
> > +    if (@unknown) {
> > +	ERROR("Saw unacceptable licenses '" . join(',', @unknown) .
> > +	      "', valid choices for QEMU are:\n" . join("\n", $prefer, @valid));
> > +    }
> > +
> > +    if ($nonpreferred) {
> > +	WARN("Saw acceptable license '$origexpr' but note '$prefer' is preferred " .
> > +	     "for new files unless the code is derived from a source with an" .
> > +	     "existed declared license that must be followed.");
> 
> Is it not preferred to contribute code under the BSD-3-clause? Based on
> other items in the project, I was expecting we could make contributions for
> hexagon w/BSD.  But those are exceptional cases and not to be followed in
> the general case?

I'm not saying people can't contribute under BSD, but if that is required,
a explanation of why is desired.

IMHO we don't want contributors choosing an non-GPL-2.0-or-later license
merely out of personal (or corporate) preferences.

We want GPL-2.0-or-later to be used for everything, unless there is a
compelling reason to diverge. The need to remain compliant with existing
code that has been incorporated is the most common & obvious reason for
this.

Other reasons likely exist - which could be explained in the commit
message, to aid reviewers who are likely to see the checkpatch warnings
about the unusal license choices.

With regards,
Daniel
diff mbox series

Patch

diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
index cc266abdcd..cd1ed90f4c 100755
--- a/scripts/checkpatch.pl
+++ b/scripts/checkpatch.pl
@@ -1353,6 +1353,67 @@  sub checkfilename {
 	}
 }
 
+sub checkspdx {
+    my ($file, $expr) = @_;
+
+    # Imported Linux headers probably have SPDX tags, but if they
+    # don't we're not requiring contributors to fix this
+    if ($file =~ m,include/standard-headers, ||
+	$file =~ m,linux-headers,) {
+	return;
+    }
+
+    my $origexpr = $expr;
+
+    # Flatten sub-expressions
+    $expr =~ s/\(|\)/ /g;
+    $expr =~ s/OR|AND/ /g;
+
+    # Merge WITH exceptions to the license
+    $expr =~ s/\s+WITH\s+/-WITH-/g;
+
+    # Cull more leading/trailing whitespace
+    $expr =~ s/^\s*//g;
+    $expr =~ s/\s*$//g;
+
+    my @bits = split / +/, $expr;
+
+    my $prefer = "GPL-2.0-or-later";
+    my @valid = qw(
+	LGPL-2.0-or-later
+	LGPL-2.1-or-later
+	GPL-2.0-only
+	LGPL-2.0-only
+	LGPL-2.0-only
+	BSD-2-Clause
+	BSD-3-Clause
+	MIT
+	);
+
+    my $nonpreferred = 0;
+    my @unknown = ();
+    foreach my $bit (@bits) {
+	if ($bit eq $prefer) {
+	    next;
+	}
+	if (grep /^$bit$/, @valid) {
+	    $nonpreferred = 1;
+	} else {
+	    push @unknown, $bit;
+	}
+    }
+    if (@unknown) {
+	ERROR("Saw unacceptable licenses '" . join(',', @unknown) .
+	      "', valid choices for QEMU are:\n" . join("\n", $prefer, @valid));
+    }
+
+    if ($nonpreferred) {
+	WARN("Saw acceptable license '$origexpr' but note '$prefer' is preferred " .
+	     "for new files unless the code is derived from a source with an" .
+	     "existed declared license that must be followed.");
+    }
+}
+
 sub process {
 	my $filename = shift;
 
@@ -1641,6 +1702,11 @@  sub process {
 		    }
 		}
 
+# Check SPDX-License-Identifier references a permitted license
+		if ($rawline =~ m,SPDX-License-Identifier: (.*?)(\*/)?\s*$,) {
+		    &checkspdx($realfile, $1);
+		}
+
 # Check for wrappage within a valid hunk of the file
 		if ($realcnt != 0 && $line !~ m{^(?:\+|-| |\\ No newline|$)}) {
 			ERROR("patch seems to be corrupt (line wrapped?)\n" .