sbt / sbt-header

sbt-header is an sbt plugin for creating file headers, e.g. copyright headers
Apache License 2.0
187 stars 55 forks source link

"Unable to auto detect project license" on aggregate project #153

Open dragos opened 6 years ago

dragos commented 6 years ago

I'm trying to upgrade to Sbt 1.0 and from sbt-header version 1.7.0 to 5.0.0 as the same time. I can't run headerCheck anymore because it crashes with:

sbt:root> headerCreate
[error] java.lang.RuntimeException: Unable to auto detect project license
[error]         at scala.sys.package$.error(package.scala:27)
[error]         at de.heikoseeberger.sbtheader.HeaderPlugin$.$anonfun$toBeScopedSettings$4(HeaderPlugin.scala:111)
[error]         at scala.Option.getOrElse(Option.scala:121)
[error]         at de.heikoseeberger.sbtheader.HeaderPlugin$.$anonfun$toBeScopedSettings$3(HeaderPlugin.scala:111)
[error]         at scala.Function1.$anonfun$compose$1(Function1.scala:44)
[error]         at sbt.internal.util.$tilde$greater.$anonfun$$u2219$1(TypeFunctions.scala:39)
[error]         at sbt.std.Transform$$anon$4.work(System.scala:66)
[error]         at sbt.Execute.$anonfun$submit$2(Execute.scala:262)
[error]         at sbt.internal.util.ErrorHandling$.wideConvert(ErrorHandling.scala:16)
[error]         at sbt.Execute.work(Execute.scala:271)

It would be good to tell me what project it is, but my guess is that this is the root aggregate project (as I'm setting project-specific settings for each subproject). I don't have any sources in root, so what's the proper solution to get past this? I don't want to define any header license for root, as it makes no sense.

EDIT: Reproducible:

lazy val leaf = (project in file("leaf")).
  settings(
    headerLicense := Some(HeaderLicense.Custom(
      """|Copyright © 2016-2017 You have the right to be happy
         |""".stripMargin
    )),
    organization := "com.example",
    scalaVersion := "2.12.4",
    version      := "0.1.0-SNAPSHOT",
    name := "test-sbt-header",
  )

headerLicense in ThisBuild := None

lazy val deps = (project in file("deps"))
  .settings(
    headerLicense := Some(HeaderLicense.Custom(
      """|Copyright © 2016-2017 You have the right to be happy
         |""".stripMargin
    )))

lazy val root = (project in file("."))
  .settings(headerLicense := None)
  .aggregate(leaf, deps)
hseeberger commented 6 years ago

What about setting headerLicense : = None in the root project?

BTW, please upgrade to 5.0.0.

dragos commented 6 years ago

I am on 5.0.0 and HeaderLicense is indeed None already.

Edit: I modified the ticket to be clear... I was upgrading from 1.7.0 to the latest version

hseeberger commented 6 years ago

Is it None for all projects (root and subprojects)?

dragos commented 6 years ago

No, the subprojects each have a headerLicense, but the root project is just a convenience and has no sources. It's not a standard license, it's a proprietary one. I got past this by adding the same headerLicense to root, but I thought setting it to None should be enough.

hseeberger commented 6 years ago

Yeah, using None should work. Do you have a reproducer?

dragos commented 6 years ago

Sure, here it is:

lazy val leaf = (project in file("leaf")).
  settings(
    headerLicense := Some(HeaderLicense.Custom(
      """|Copyright © 2016-2017 You have the right to be happy
         |""".stripMargin
    )),
    organization := "com.example",
    scalaVersion := "2.12.4",
    version      := "0.1.0-SNAPSHOT",
    name := "test-sbt-header",
  )

lazy val deps = (project in file("deps"))
  .settings(
    headerLicense := Some(HeaderLicense.Custom(
      """|Copyright © 2016-2017 You have the right to be happy
         |""".stripMargin
    )))

lazy val root = (project in file("."))
  .settings(headerLicense := None)
  .aggregate(leaf, deps)

There's nothing else in there except the plugins.sbt with sbt-header coordinates.

Then this happens:

sbt:root> headerCheck
[error] java.lang.RuntimeException: There are files without headers!
[error]   /Users/dragos/sandbox/test-sbt-header/leaf/src/main/scala/example/Hello.scala
[error]
[error]         at scala.sys.package$.error(package.scala:27)
[error]         at de.heikoseeberger.sbtheader.HeaderPlugin$.checkHeadersTask(HeaderPlugin.scala:178)
[error]         at de.heikoseeberger.sbtheader.HeaderPlugin$.$anonfun$toBeScopedSettings$5(HeaderPlugin.scala:120)
[error]         at scala.Function1.$anonfun$compose$1(Function1.scala:44)
[error]         at sbt.internal.util.$tilde$greater.$anonfun$$u2219$1(TypeFunctions.scala:39)
[error]         at sbt.std.Transform$$anon$4.work(System.scala:66)
[error]         at sbt.Execute.$anonfun$submit$2(Execute.scala:262)
[error]         at sbt.internal.util.ErrorHandling$.wideConvert(ErrorHandling.scala:16)
[error]         at sbt.Execute.work(Execute.scala:271)
[error]         at sbt.Execute.$anonfun$submit$1(Execute.scala:262)
[error]         at sbt.ConcurrentRestrictions$$anon$4.$anonfun$submitValid$1(ConcurrentRestrictions.scala:174)
[error]         at sbt.CompletionService$$anon$2.call(CompletionService.scala:36)
[error]         at java.util.concurrent.FutureTask.run(FutureTask.java:266)
[error]         at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
[error]         at java.util.concurrent.FutureTask.run(FutureTask.java:266)
[error]         at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
[error]         at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
[error]         at java.lang.Thread.run(Thread.java:748)
[error] java.lang.RuntimeException: Unable to auto detect project license
[error]         at scala.sys.package$.error(package.scala:27)
[error]         at de.heikoseeberger.sbtheader.HeaderPlugin$.$anonfun$toBeScopedSettings$6(HeaderPlugin.scala:118)
[error]         at scala.Option.getOrElse(Option.scala:121)
[error]         at de.heikoseeberger.sbtheader.HeaderPlugin$.$anonfun$toBeScopedSettings$5(HeaderPlugin.scala:118)
[error]         at scala.Function1.$anonfun$compose$1(Function1.scala:44)
[error]         at sbt.internal.util.$tilde$greater.$anonfun$$u2219$1(TypeFunctions.scala:39)
[error]         at sbt.std.Transform$$anon$4.work(System.scala:66)
[error]         at sbt.Execute.$anonfun$submit$2(Execute.scala:262)
[error]         at sbt.internal.util.ErrorHandling$.wideConvert(ErrorHandling.scala:16)
[error]         at sbt.Execute.work(Execute.scala:271)
[error]         at sbt.Execute.$anonfun$submit$1(Execute.scala:262)
[error]         at sbt.ConcurrentRestrictions$$anon$4.$anonfun$submitValid$1(ConcurrentRestrictions.scala:174)
[error]         at sbt.CompletionService$$anon$2.call(CompletionService.scala:36)
[error]         at java.util.concurrent.FutureTask.run(FutureTask.java:266)
[error]         at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
[error]         at java.util.concurrent.FutureTask.run(FutureTask.java:266)
[error]         at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
[error]         at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
[error]         at java.lang.Thread.run(Thread.java:748)
[error] java.lang.RuntimeException: Unable to auto detect project license
[error]         at scala.sys.package$.error(package.scala:27)
[error]         at de.heikoseeberger.sbtheader.HeaderPlugin$.$anonfun$toBeScopedSettings$6(HeaderPlugin.scala:118)
[error]         at scala.Option.getOrElse(Option.scala:121)
[error]         at de.heikoseeberger.sbtheader.HeaderPlugin$.$anonfun$toBeScopedSettings$5(HeaderPlugin.scala:118)
[error]         at scala.Function1.$anonfun$compose$1(Function1.scala:44)
[error]         at sbt.internal.util.$tilde$greater.$anonfun$$u2219$1(TypeFunctions.scala:39)
[error]         at sbt.std.Transform$$anon$4.work(System.scala:66)
[error]         at sbt.Execute.$anonfun$submit$2(Execute.scala:262)
[error]         at sbt.internal.util.ErrorHandling$.wideConvert(ErrorHandling.scala:16)
[error]         at sbt.Execute.work(Execute.scala:271)
[error]         at sbt.Execute.$anonfun$submit$1(Execute.scala:262)
[error]         at sbt.ConcurrentRestrictions$$anon$4.$anonfun$submitValid$1(ConcurrentRestrictions.scala:174)
[error]         at sbt.CompletionService$$anon$2.call(CompletionService.scala:36)
[error]         at java.util.concurrent.FutureTask.run(FutureTask.java:266)
[error]         at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
[error]         at java.util.concurrent.FutureTask.run(FutureTask.java:266)
[error]         at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
[error]         at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
[error]         at java.lang.Thread.run(Thread.java:748)
[error] (leaf / Compile / headerCheck) There are files without headers!
[error]   /Users/dragos/sandbox/test-sbt-header/leaf/src/main/scala/example/Hello.scala
[error] (deps / Compile / headerCheck) Unable to auto detect project license
[error] (Compile / headerCheck) Unable to auto detect project license
[error] Total time: 0 s, completed Mar 7, 2018 10:24:50 AM
sbt:root>
hseeberger commented 6 years ago

@britter could you take a look, please? For some reason ther root project complains "Unable to auto detect project license" although headerLicense is set to None.

britter commented 6 years ago

I'll try to have a look on friday

timaschew commented 6 years ago

Is this project still alive?

I have the same issue, can't use the plugin at all.

britter commented 6 years ago

I don't have the time to look into this at the moment. Help in analysis or even PRs to fix this are welcome.

helena commented 6 years ago

@dragos @hseeberger I ran into this as well running sbt headerCreate, and fixed it by adding licenses += (...) to my root project in a multi-module. The issue was raised when I only had it in settings for the lib modules.

hseeberger commented 5 years ago

@helena thanks for picking this up.

If we choose to set headerLicense := None, which is the default (!), then the plugin tries to be smart and auto-detect the license from the standard licenses setting. If this is empty, which again is the default (!), we are f...ed (to speak with Tyrion Lanister).

Maybe the semantics should be changed: instead of failing we could simply not check/create headers at all for these cases.

What do others think?

BTW, I never run into this issue, because I define the license and other stuff like the Scala version in a lazy val commonSettings which I add to all modules including the root project. Not saying that this makes a lot of sense, but at least it has proven to be convenient.

hseeberger commented 5 years ago

@timaschew thanks for your very motivating comment, this is what makes working on open source software real fun.

lucasbru commented 5 years ago

@hseeberger Yes, please only check or create licenses if licenses is non-empty or headerLicense is set. Our adoption is blocked by this issue as well.

hseeberger commented 5 years ago

@lucasbru PR welcome

helena commented 5 years ago

I suggest not raising an exception in de.heikoseeberger.sbtheader.HeaderPlugin if the plugin is added to an SBT project but not explicitly added to a particular module. For example, requiring sbt.Keys.licenses in a root module, which may not be published or used, seems out of scope of a plugin and more in the realm of SBT usage. But if one explicitly ads sbt.Keys.licenses as noted in the README, for say Apache, or headerLicense for a custom, then a user would want to be checked and notified of what is incorrect.

@hseeberger I bet your usage is more typical, where users would add buildSettings or commonSettings from a lazy val to all modules in a multi. In a simple in-line no module build.sbt it wouldn't be an issue.

2m commented 3 years ago

As a workaround I disabled the plugin on the root project by adding:

disablePlugins(HeaderPlugin)
danicheg commented 5 months ago

Someone in this thread suggested setting headerLicense := None but the code throwing the exception checks for non-emptiness 🤔 https://github.com/sbt/sbt-header/blob/master/src/main/scala/de/heikoseeberger/sbtheader/HeaderPlugin.scala#L145-L152 For anyone facing this issue, setting organizationName, licenses and startYear in the root project or for the entire build (via ThisBuild) resolved the issue for me.

rafafrdz commented 2 months ago

For some you guys who are still facing this issue, here is an example that works for me:

lazy val root = (project in file("."))
  .disablePlugins(AssemblyPlugin, HeaderPlugin)
  .aggregate(leaf, deps)

lazy val leaf = (project in file("leaf"))
  .settings(
    headerLicense := Some(header)
  )

lazy val deps = (project in file("deps"))
  .settings(
    headerLicense := Some(header)
  )

val header: License.Custom = HeaderLicense.Custom(
  """|Copyright © 2016-2017 You have the right to be happy
     |""".stripMargin
)