feat: tool/copyright - #4983
Conversation
Checks the claims in the headers against git history and reports any organization with no contribution behind it. -w removes them. Needs -dates, and skips a file when a contributor's affiliation is unknown.
|
Is there a documentation of what is required? The additional copyright information seems to be just a duplicate? The individual authors with date can be derived from the commit history. Separately, how about adopting the REUSE recommendation with SPDX identifier: |
Yes, I'm all for it! I think a short: // SPDX-License-Identifier: Apache-2.0is better than the entire license boilerplate we have right now in each file: // Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.But I wanted to keep it out of this PR. This change would belong to another PR. |
Legally speaking, this PR changes nothing and is not supposed to change anything about licenses and copyright claims. It only adds a new tool that can help automate bumping/updating the copyright claims we have right now. I can just run The history-rewrite functionality that it provides is not used in this PR yet. We may or may not use it to clean up the entire codebase in a later PR. Changing the way we do copyright claims, attributions and license disclosure is not in the scope of this PR. |
|
So what do these scripts actually do? To me the example looked like they added author email, date, and commit hash to the copyright? If they do something else then I misunderstood what the scripts are meant to do... |
No. Nothing changes in that regard.
If I change a bunch of files and I'm listed under affiliations.json: {
"name": "Roman Sharkov",
"emails": ["roman.scharkov@gmail.com", "rsc@scion.org"],
"affiliation": "SCION Association"
}then:
// Copyright 2026 SCION Association
What it also can do is rewrite claims in a sub-tree of the repository with: make copyright-update COPYRIGHT_FLAGS="-history $PWD/tools/copyright/affiliation-history.json"
|
tzaeschke
left a comment
There was a problem hiding this comment.
In summary:
- I think the documentation could be cleaned up a bit
- It is unclear to me why we need a history file and why it needs to be private (outside the repo)
- It still seems to me that the scripts may add committer name + date + commit ID (at least of someone is not listed in the affiliation file?). I don't fully understand what the point is and also I don't quite understand whether this is temporary or will actually be committed.
| go run ./tools/copyright -w -history tools/copyright/affiliation-history.json | ||
| ``` | ||
|
|
||
| `.gitignore` reserves that path, but the file may live anywhere. Through `make`, |
There was a problem hiding this comment.
| `.gitignore` reserves that path, but the file may live anywhere. Through `make`, | |
| `.gitignore` excludes that path from being committed, but the file may live anywhere. Through `make`, |
There was a problem hiding this comment.
Also, maybe the path shouldn't be hardcoded in .gitignore if it can live anywhere? Usually, I'd say, ignored file should live in the project root or a dedicated subfolder, not somewhere in the code?
| @@ -0,0 +1,167 @@ | |||
| # copyright | |||
|
|
|||
| See [doc.go](doc.go), or `go doc ./tools/copyright`. | |||
There was a problem hiding this comment.
I find it a bit confusing that part of the documentation lives in README and the other part in doc.go.
Maybe merge them?
Also, it seems the reading order is README.md, the doc.go.
|
|
||
| ## affiliation-history.json | ||
|
|
||
| People change employer while keeping the same address, and the snapshot has |
There was a problem hiding this comment.
I don´t quite understand this. What is the snapshot and how can it drop things?
What is "others", does it refer to employers?
It is also not clear to me why we need this history?
Either people claim their copyright correctly, or they don't. If they don't, then it probably doesn't help if someone keeps in unofficial file on their personal device that somehow records this history? I don't see any legal or practical benefit from that (but I am not a lawyer).
| ``` | ||
|
|
||
| ```sh | ||
| go run ./tools/copyright -w -history tools/copyright/affiliation-history.json |
There was a problem hiding this comment.
Why is the hostory private? I think, git history should contain all that information publicly?
There was a problem hiding this comment.
I initially raised a concern to Roman about this. Then he mentioned that this is anyway public in Git history. So if that is the case, we can keep this file public too
There was a problem hiding this comment.
So if it is in the git history, why store it in a file?
| By default it reports how many files are out of date, and which identities it could not | ||
| attribute. Under `-v`, every line it adds or moves cites the contribution behind it: | ||
|
|
||
| ```txt |
There was a problem hiding this comment.
This example looks very much like it is adding lines with attribution date and commit ID. Is it not?
Maybe explain what this example shows: to me this looks like the output of diff, i.e. "+" means a line is added "-" means a line is removed.
| // # report what is out of date here and below, exit non-zero if anything is | ||
| // go run ./tools/copyright | ||
| // # bring this subtree's headers up to date | ||
| // go run ./tools/copyright -w |
There was a problem hiding this comment.
The -w option is not mentioned in the text above. I assume id does "write"?
| // Dating every revision is what puts the whole history back in scope, | ||
| // so -history ignores -base. | ||
| // | ||
| // Each line the report adds or moves cites the contribution it rests on: |
There was a problem hiding this comment.
What "report"? That was not mentioned before?
Also, why does a report add or move lines? I would expect it to be read-only?
| // claim it for whoever its author works for today. | ||
| // -base defaults to origin/master, and an empty one reads the whole history. | ||
| // | ||
| // -history points at an optional file that dates the affiliations instead, |
There was a problem hiding this comment.
Maybe this whole text could be restructured a bit? It seems to be a mixture of explaining argument flags and explaining what the tools does. Maybe explain first what the too does and then list all flags with an explanation?
| // A run therefore reads only the commits -base does not reach, the work on this branch, | ||
| // where that snapshot is current by definition. Everything -base reaches is settled: |
There was a problem hiding this comment.
| // A run therefore reads only the commits -base does not reach, the work on this branch, | |
| // where that snapshot is current by definition. Everything -base reaches is settled: | |
| // A run therefore reads only the commits that -base does not reach: the work on this branch, | |
| // where that snapshot is current by definition. Everything -base reaches is settled: |
Clarify what "work on this branch" refers to.
| // A run therefore reads only the commits -base does not reach, the work on this branch, | ||
| // where that snapshot is current by definition. Everything -base reaches is settled: |
There was a problem hiding this comment.
Can you specify what a "run" is? Is it independent of the arguments? Does it require -w? Is it independent of specifying -base?
A task I long wanted to automate, assisted with Claude Code (Opus 5)
It makes copyright claims easier to maintain.
This PR does not change any copyright claims, it only begins to enforce them starting with
attributions.jsonsince2026-09-01. I kept history changes out of this PR to avoid blowing the scope. We can do a general cleanup in a later PR.Adds
make copyright-checkandmake copyright-update:user.emailcopyright-update, making it harder to miss.Alternatives Analysis
I haven't found an off the shelf tool that does what we need.
DISCLAIMER: I did use Claude Code (Opus 5) to generate this table so keep in mind that there can be mistakes even though I tried to check some of them manually:
tools/copyrightREUSE.tomlUpdateCopyrightsActioncopyright.py.golangci.yml)