contributing: Use SPDX copyright tags in file headers - #7743
Conversation
|
AI-review as is (not counting prompting and adjustments) since this is difficult to review for humans (edit, it slipped without my prefix): I checked the claims in the description against the diff itself, without using the conversion script, by parsing the patches this PR reports. Every added line matches one of two shapes, lib/psdriver/psdriver.ps is invisible in the diff viewGitHub reports the file as The practical consequence is that this file cannot be reviewed in the web UI, so it needs It also explains the file count arithmetic, which otherwise looks like drift: the local diff is +2142/-5365, this PR reports +2139/-5354, and the gap is exactly 3 additions and 11 deletions, which is precisely psdriver.ps. Nothing is missing from the PR; GitHub is not counting a file it thinks is binary. Worth a line in the description so nobody has to work that out. The validators are less independent than the count suggestsThe description lists a set of checks, and they did all pass, but they are not all independent evidence. The validator script imports the converter and calls it to recompute each header span, so the span-integrity and token-conservation checks compare the converter against its own expectation. A systematically wrong span finder would produce a matching wrong expectation and pass both. The checks that are genuinely independent are the ones that do not go through the converter:
That is roughly three independent facts plus a set of consistency checks, which is enough for a mechanical conversion of this shape, but the list should not be read as a dozen separate confirmations. For a one-off script I would not restructure this; it is worth knowing when weighing how much the passing checks prove. On sequencingThe description is right that this should not merge before |
Replace the COPYRIGHT field and the GPL paragraph with SPDX tags in the 984 files where the conversion is mechanical. The notice text is the only input: neither AUTHOR(S) nor the git history was consulted. Years are copied verbatim, including where they are plainly wrong, such as 2002-20014 in v.net.connectivity. Correcting them is a separate question from converting the header, and guessing at them is how the previous attempt invented copyright holders. The collective line carries years only where it is the sole copyright line. Where a holder is named, the named line carries the years and the collective line is bare. COPYING defines the collective. 31 files are left untouched and reported separately: notices naming several holders where the punctuation is ambiguous, notices with more than one copyright clause, three files under the LGPL, and two where a field interrupts the header. lib/vector/rtree/docs/MAILS is excluded outright, being an archived email that quotes a header rather than carrying one. The headers that define the convention are converted in a separate pull request, and the roughly 1300 files whose notices use the bare (C) form without a COPYRIGHT field are out of scope here. The conversion was performed by a deterministic script, not by a language model. The script and its report are attached to the pull request. It was written with AI assistance (Claude Opus 4.8); the decisions are the author's.
|
I really do not understand the incentive to change copyright holder in the proposed way (or any other for that matter), and then describe the change in another file (that it means the same thing as before!?). It looks particularly strange when "GRASS Development Team" is the only copyright holder: - * COPYRIGHT: (C) 2008 by the GRASS Development Team
- *
- * This program is free software under the GNU General Public
- * License (>=v2). Read the file COPYING that comes with GRASS
- * for details.
+ * SPDX-FileCopyrightText: Other GRASS authors
+ * SPDX-License-Identifier: GPL-2.0-or-later |
|
The "collective author" makes more sense in the files with multiple authors which we may eventually get in the future, but I was purposefully not reading from the author field in this iteration. The old GRASS Development Team is not well defined and misleading, but some future effort will have to clean up that. (Our governance has Core Development Team which is a different entity.) The particular wording is not ideal, but I/we at the community meeting did not find anything better yet. (As for AI suggestions, Fable was suggesting to drop it.) As for general need for this, @neteler is the one who initiated this. |
Let us bring this seemingly trivial issue to the grass dev discourse list, before merge. I’m not convinced. |
|
Sounds good to me, but I can lead only the implementation part at this point. No problem updating my PRs (but no promises on my response time right now). |
Replaces the
COPYRIGHT:field and the GPL paragraph with SPDX tags in the 984 files where the conversion is mechanical.A typical replacements looks like this:
The policy decisions were made during GRASS Community Meeting 2026 in San Michele all'Adige.
Addresses partially #4190. Supersedes #7556, #7557, #7729 and #7716.
Details: rules, scope, deferred cases, and how it was checked (AI generated)
Rules
SPDX-FileCopyrightTextline. Named holders first, the collective line last, the license identifier after all copyright lines.v.net.connectivitykeeps2002-20014;g.gui.timelinekeeps2012-13. Those years are wrong, but they were already wrong, and fixing them is a separate question from converting the header.lib/lidar/*(Politecnico di Milano),imagery/i.topo.corr/*(E. Jorge Tizado) andlib/psdriver/*(Glynn Clements), and they gainSPDX-FileCopyrightText: Other GRASS authorsalongside the existing holder. This is deliberate rather than a side effect of the pattern matching:COPYINGstates that GRASS is copyright by members of the GRASS Development Team, so the collective already holds copyright in those files and the per-file notice was merely incomplete. The named holder is preserved exactly and loses nothing by it. It is the one place where a converted notice says something the old text did not, so it is called out here rather than left to be discovered file by file.AUTHOR(S)nor the git history was consulted, so holder names are copied as written:v.reportkeepsMN,r.drainkeepsmetz,r.tilesetkeeps the misspelledCedric Shoc. Normalizing them means readingAUTHOR(S)to decide a copyright holder, which is a follow-up with a person in the loop, not a regex.MODULE:,AUTHOR(S):andPURPOSE:are untouched, as is every byte outside the header span.Scope
git grep -lE 'COPYRIGHT:[[:space:]]*\([Cc]\)'Out of scope: roughly 1300 files whose notices use the bare
(C)form with noCOPYRIGHT:field, mostlylib/Doxygen blocks and wxGUI docstrings. This PR converts theCOPYRIGHT:-field corpus only, so the tree is left in a mixed state on purpose.Depends on a follow-up
This PR puts
Other GRASS authorsin 984 files, andCOPYINGdoes not define that term yet. A follow-up adds the definition and handles the five files that specify the convention rather than merely carrying it:doc/development/style_guide.md,lib/gis/parser_script.c,general/g.parser/g.parser.mdand.html, andutils/copywrite.pl. They are excluded here because each of them states what a header should look like, so they need reading rather than converting, and because two of them generate headers into new files.RFC 2 says existing copyright headers must not be stripped without agreement. Renaming the collective in 984 files is a notational change rather than a change of holder only because the project writes down that the two names mean the same group — which is what the
COPYINGdefinition does. So this should not merge before that definition lands, even though it can be reviewed now.Not converted
The 31 deferred files are attached as
deferred-cases.md, quoted verbatim with the reason each was left alone. Summary:and. Such punctuation separates two holders inCedric Shoc, Martin Landaand sits inside one holder inmundialis GmbH & Co.KGandGDF Hannover bR, http://www.gdf-hannover.de. The notice alone cannot tell them apart.v.delaunayfiles carrying(C) RMIT 1993alongside the GRASS notice.i.albedo,i.aster.toar,i.evapo.time. Converting those toGPL-2.0-or-laterwould misstate the license.lib/vector/rtree/docs/MAILSis excluded outright: line 134 is a>-quoted 2001 email asking permission to add GRASS headers. It quotes a header rather than carrying one, and rewriting it would falsify a record.How it was done, and how to check it
A deterministic script, not a language model. It is attached (
spdx_headers.py.txt) together with its tests (spdx_headers_test.py.txt) and the validators (gates.py.txt), so the result can be reproduced or regenerated against a newer base. It is not committed, being a one-off: the repository already carries one abandoned header generator from 2006,utils/copywrite.pl, which has been unrunnable for years and is itself a conversion target.The script keys on
COPYRIGHT:\s*\([Cc]\), so a second run is a no-op by construction. It edits by byte-offset splice and never rebuilds a file from a line list, which is why no trailing newline can drift.Validators, all run against the raw output before any formatter touched it:
pre-commit run --all-filesleaves the output byte-identical — 21 hooks, no reformatting.29 tests cover the harness, including every comment syntax in the tree (
*,#,##,%, CMake#[[, undecorated), the verbatim-year table, and one case per deferral reason.The conversion itself was performed by the script above. The script, the analysis behind it, and this description were written with AI assistance (Claude Code with Opus 4.8 and Fable 5).
deferred-cases.md
gates.py.txt
spdx_headers_test.py.txt
spdx_headers.py.txt