[PATCH 2/3] scripts: validate SPDX license choices

Daniel P. Berrangé posted 3 patches 1 month, 2 weeks ago
There is a newer version of this series
[PATCH 2/3] scripts: validate SPDX license choices
Posted by Daniel P. Berrangé 1 month, 2 weeks ago
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.");
+    }
+}
+
 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" .
-- 
2.46.0


Re: [PATCH 2/3] scripts: validate SPDX license choices
Posted by Brian Cain 1 month, 2 weeks ago
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" .

Re: [PATCH 2/3] scripts: validate SPDX license choices
Posted by Daniel P. Berrangé 1 month, 2 weeks ago
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
-- 
|: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org         -o-            https://fstop138.berrange.com :|
|: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|