Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

updateYearWithLatest(false) is ignored/doesn't work #677

Closed
ZacSweers opened this issue Aug 28, 2020 · 5 comments
Closed

updateYearWithLatest(false) is ignored/doesn't work #677

ZacSweers opened this issue Aug 28, 2020 · 5 comments
Labels

Comments

@ZacSweers
Copy link
Contributor

When running with .updateYearWithLatest(false) on this PR, all the existing copyright headers are updated to 2020 anyway. Is there another configuration we're missing?

kotlin {
  ktlint("0.38.0").userData(mapOf("indent_size" to "2"))
  target("**/*.kt")
  trimTrailingWhitespace()
  endWithNewline()
  licenseHeaderFile("spotless/spotless.kt")
    .updateYearWithLatest(false)
  targetExclude("**/Dependencies.kt", "**/spotless.kt")
}

Spotless version: 0.38.0
macOS 10.15.6

@nedtwigg
Copy link
Member

I agree this behavior is surprising, but it's tricky to fix. Here is the diff which is causing the headers to update even though you don't want them to:

- *      http://www.apache.org/licenses/LICENSE-2.0
+ *    https://www.apache.org/licenses/LICENSE-2.0

Note the two fewer spaces, and the http to https. Because of that, Spotless says "this file doesn't have a license, I'll put one on." The parsing it does to determine if the file has a license is precise, no fuzz:

beforeYear = licenseHeader.substring(0, yearTokenIndex);
afterYear = licenseHeader.substring(yearTokenIndex + yearToken.get().length());

workaround

For the files which are being updated and you don't want them to be, use some manual regex work to set the right number of spaces and http vs https, and then Spotless will recognize the header and not change the year.

Better workflow, imo

I think the behavior you're reasonably expecting is that the licenseHeader step would do some kind of fuzzy copyright-year extraction, whatever the current copyright header is, and use that year? And maybe you also want it to slurp out the author? The trick is that projects with fuzzy copyright years tend to also have fuzzy copyright ownership in general. Just flipping through the first few files, I see some Copyright (C) 2011 FasterXML, LLC in Iso8601Utils, (C) 2011 Google Inc. in PolymorphicJsonAdapterFactory. Do you want to preserve those authors?

I want to preserve my existing copyright headers

I think the right default for Spotless, in every application, is ratchetFrom 'origin/main'. Even if you don't care about the diff noise of a single "format-everything" commit, every bugfix in your formatter cascades into diff noise, and ratchetFrom fixes that. Besides, ratchetFrom is a speed boost.

It also keeps the copyright info more accurate - if you have a file which was authored in 2016, but updated in 2020, both of those dates should be in the notice. By updating copyright years to today, but only when a file has changed, you achieve that.

updateYearWithLatest(false) is the default value, you don't need to set it, and it is how the license step has worked since its inception. With ratchetFrom, only then did we introduce the option to set it to true, which is the default when ratcheting, and it is imo the best way to do copyright headers.

My copyright headers have been sloppy, and I want to preserve their history, but blast them into conformity

Then you should use ratchetFrom 'origin/main', and do a single run with -PspotlessSetLicenseHeaderYearsFromGitHistory=true. That run will be very slow and slurp them from git history. But from then on they'll be right, and they'll stay right.

Regardless of the above, I want to preserve variances in authors

If you want to keep Google and FasterXML in the copyright headers on the two random files, then Spotless' license header step can't help, as of today. It isn't smart enough to parse that out. The fix would be #323, which isn't on my personal roadmap.

@nedtwigg
Copy link
Member

nedtwigg commented Sep 3, 2020

I've thought about this a bit, and it seems like if only the beforeYear part matches, we could still parse out the year pretty easily, and that would probably be less surprising. If we did that - parse and preserve the year when beforeYear matches, even though the afterYear part does not, would that be closer to your expectation, @ZacSweers?

@nedtwigg
Copy link
Member

We implemented the most permissive thing I could think of. If there's an existing header, it looks for the first two 4-digit years it can find. If it only finds one, it uses that, if it finds two, it uses them like first-last. Released in plugin-gradle 5.5.0 and plugin-maven 2.3.0.

@ZacSweers
Copy link
Contributor Author

Sorry for the delay in circling back to this! Your solution sounds great, thanks for the quick turnaround

@nedtwigg
Copy link
Member

No worries, thanks for telling us about a pain point :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants