diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs new file mode 100644 index 0000000..81e0f79 --- /dev/null +++ b/.git-blame-ignore-revs @@ -0,0 +1,2 @@ +# Scala Steward: Reformat with scalafmt 3.6.1 +6a9fa7b0bb88cd7273e10ef9532be96fafdab867 diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..5ace460 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,6 @@ +version: 2 +updates: + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 7d7900b..7cc10fc 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -2,16 +2,26 @@ name: Release on: push: - tags: ["*"] + tags: ["**"] jobs: publish: - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest + env: + # define Java options for both official sbt and sbt-extras + JAVA_OPTS: -Xms2048M -Xmx2048M -Xss6M -XX:ReservedCodeCacheSize=256M -Dfile.encoding=UTF-8 + JVM_OPTS: -Xms2048M -Xmx2048M -Xss6M -XX:ReservedCodeCacheSize=256M -Dfile.encoding=UTF-8 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v5 with: fetch-depth: 0 - - uses: olafurpg/setup-scala@v13 + - name: Setup JDK + uses: actions/setup-java@v5 + with: + distribution: "zulu" + java-version: 8 + cache: sbt + - uses: sbt/setup-sbt@v1 - run: sbt ci-release env: PGP_PASSPHRASE: ${{ secrets.PGP_PASSPHRASE }} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index bbb48ee..90da9f2 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -2,18 +2,45 @@ name: Test on: push: - branches: [ master ] + branches: [ master, main ] pull_request: - branches: [ master ] + branches: [ master, main ] jobs: build: - runs-on: ubuntu-20.04 + strategy: + fail-fast: false + matrix: + include: + - os: ubuntu-latest + jobtype: 1 + - os: ubuntu-latest + jobtype: 2 + - os: ubuntu-latest + jobtype: 3 + runs-on: "${{ matrix.os }}" + env: + # define Java options for both official sbt and sbt-extras + JAVA_OPTS: -Xms2048M -Xmx2048M -Xss6M -XX:ReservedCodeCacheSize=256M -Dfile.encoding=UTF-8 + JVM_OPTS: -Xms2048M -Xmx2048M -Xss6M -XX:ReservedCodeCacheSize=256M -Dfile.encoding=UTF-8 steps: - - uses: actions/checkout@v2 - - uses: actions/setup-java@v2 + - uses: actions/checkout@v5 + - name: Setup JDK + uses: actions/setup-java@v5 with: - distribution: adopt - java-version: 11 - - uses: coursier/cache-action@v5 - - run: sbt scripted + distribution: "zulu" + java-version: 8 + cache: sbt + - uses: sbt/setup-sbt@v1 + - name: Build and test + if: ${{ matrix.jobtype == 1 }} + shell: bash + run: sbt -v '++ 2.12.x' test scripted + - name: Build and test (Scala 3) + if: ${{ matrix.jobtype == 2 }} + shell: bash + run: sbt -v '++ 3.x' test scripted + - name: Scalafmt + if: ${{ matrix.jobtype == 3 }} + shell: bash + run: sbt -v scalafmtSbtCheck +scalafmtCheckAll +headerCheckAll diff --git a/.scalafmt.conf b/.scalafmt.conf index a47e59b..8e0d45a 100644 --- a/.scalafmt.conf +++ b/.scalafmt.conf @@ -1,7 +1,7 @@ -version = "3.6.0" +version = "3.9.9" preset = "defaultWithAlign" -runner.dialect = "scala213" +runner.dialect = "Scala212Source3" maxColumn = 100 indentOperator.preset = "spray" @@ -10,3 +10,13 @@ spaces.inImportCurlyBraces = true rewrite.rules = ["AsciiSortImports", "RedundantBraces", "RedundantParens"] docstrings.blankFirstLine = true trailingCommas = "preserve" +rewrite.scala3.convertToNewSyntax = true +runner.dialectOverride.allowSignificantIndentation = true +runner.dialectOverride.allowAsForImportRename = false +runner.dialectOverride.allowStarWildcardImport = false + +fileOverride { + "glob:**/scala-3/**" { + runner.dialect = Scala3 + } +} diff --git a/README.md b/README.md index 12e6d1e..bda0209 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ sbt-header is an [sbt](http://www.scala-sbt.org) plugin for creating or updating In order to add the sbt-header plugin to your build, add the following line to `project/plugins.sbt`: ``` scala -addSbtPlugin("de.heikoseeberger" % "sbt-header" % "5.6.0") // Check the latest version above or look at the release tags +addSbtPlugin("com.github.sbt" % "sbt-header" % "5.6.0") // Check the latest version above or look at the release tags ``` Then in your `build.sbt` configure the following settings: @@ -17,7 +17,7 @@ Then in your `build.sbt` configure the following settings: ```scala organizationName := "Heiko Seeberger" startYear := Some(2015) -licenses += ("Apache-2.0", new URL("https://www.apache.org/licenses/LICENSE-2.0.txt")) +licenses += ("Apache-2.0", url("https://www.apache.org/licenses/LICENSE-2.0.txt")) ``` This configuration will apply Apache License 2.0 headers to Scala and Java files. sbt-header provides two tasks: `headerCreate` and `headerCheck`, which are described in the following sub sections. For more information on how to customize sbt-header, please refer to the [Configuration](#configuration) section. @@ -71,7 +71,7 @@ This will also be given precedence if a license has been auto detected from proj ### Build in licenses -The most common licenses have been pre-canned in [License](https://github.com/sbt/sbt-header/blob/master/src/main/scala/de/heikoseeberger/sbtheader/License.scala). They can either be detected using their SPDX identifier or by setting them explicitly. +The most common licenses have been pre-canned in [License](https://github.com/sbt/sbt-header/blob/master/src/main/scala/sbtheader/License.scala). They can either be detected using their SPDX identifier or by setting them explicitly. |License|SPDX identifier| |-------|---------------| @@ -132,7 +132,7 @@ Note that you don't need to add comment markers like `//` or `/*`. The comment s ### Configuring comment styles -Comment styles are configured on a per file type basis. The default is to apply C Style block comments to Scala and Java files. No other comment styles are predefined. If you want to create comments for example for your XML files, you have to add the corresponding mapping manually (see below). The build-in comment styles are defined in [CommentStyle](https://github.com/sbt/sbt-header/blob/master/src/main/scala/de/heikoseeberger/sbtheader/CommentStyle.scala): +Comment styles are configured on a per file type basis. The default is to apply C Style block comments to Scala and Java files. No other comment styles are predefined. If you want to create comments for example for your XML files, you have to add the corresponding mapping manually (see below). The build-in comment styles are defined in [CommentStyle](https://github.com/sbt/sbt-header/blob/master/src/main/scala/sbtheader/CommentStyle.scala): |Name|Description| |----|-----------| @@ -191,7 +191,7 @@ headerEmptyLine := false If your build uses an auto plugin for common settings, make sure to add `HeaderPlugin` to `requires`: ``` scala -import de.heikoseeberger.sbtheader.HeaderPlugin +import sbtheader.HeaderPlugin object Build extends AutoPlugin { override def requires = ... && HeaderPlugin @@ -235,7 +235,7 @@ project), the Twirl templates have to be added to the sources handled by sbt-hea definition: ```scala -import de.heikoseeberger.sbtheader.FileType +import sbtheader.FileType import play.twirl.sbt.Import.TwirlKeys headerMappings := headerMappings.value + (FileType("html") -> HeaderCommentStyle.twirlStyleBlockComment) diff --git a/bak/play-twirl/project/test.sbt b/bak/play-twirl/project/test.sbt index 6d337f1..654af30 100644 --- a/bak/play-twirl/project/test.sbt +++ b/bak/play-twirl/project/test.sbt @@ -2,4 +2,4 @@ val pluginVersion = sys.props .get("plugin.version") .getOrElse(sys.error("Sys prop plugin.version must be defined!")) -addSbtPlugin("de.heikoseeberger" % "sbt-header" % pluginVersion) +addSbtPlugin("com.github.sbt" % "sbt-header" % pluginVersion) diff --git a/bak/play-twirl/test.sbt b/bak/play-twirl/test.sbt index 4866183..33e8701 100644 --- a/bak/play-twirl/test.sbt +++ b/bak/play-twirl/test.sbt @@ -11,8 +11,8 @@ checkFileContents := { checkFile("views/main.scala.html") def checkFile(name: String) = { - val actualPath = (scalaSource.in(Compile).value / name).toString - val expectedPath = (scalaSource.in(Compile).value / (name + "_expected")).toString + val actualPath = (Compile / scalaSource).value / name).toString + val expectedPath = (Compile / scalaSource).value / (name + "_expected")).toString val actual = scala.io.Source.fromFile(actualPath).mkString val expected = scala.io.Source.fromFile(expectedPath).mkString diff --git a/build.sbt b/build.sbt index cde2336..106ebe8 100644 --- a/build.sbt +++ b/build.sbt @@ -2,14 +2,18 @@ // Build settings // ***************************************************************************** +val scala212 = "2.12.20" +val scala3 = "3.7.2" + inThisBuild( Seq( - organization := "de.heikoseeberger", - organizationName := "Heiko Seeberger", - startYear := Some(2015), - licenses += ("Apache-2.0", url("http://www.apache.org/licenses/LICENSE-2.0")), + crossScalaVersions := List(scala212, scala3), + organization := "com.github.sbt", + organizationName := "sbt plugins contributors", + startYear := Some(2015), + licenses += License.Apache2, homepage := Some(url("https://github.com/sbt/sbt-header")), - scmInfo := Some( + scmInfo := Some( ScmInfo( url("https://github.com/sbt/sbt-header"), "git@github.com:sbt/sbt-header.git" @@ -23,17 +27,26 @@ inThisBuild( url("https://github.com/hseeberger") ) ), - // scalaVersion defined by sbt - scalacOptions ++= Seq( + scalacOptions ++= List( "-unchecked", "-deprecation", - "-language:_", "-encoding", "UTF-8", - "-Ywarn-unused:imports", ), - scalafmtOnCompile := true, - dynverSeparator := "_", // the default `+` is not compatible with docker tags + scalacOptions ++= { + scalaBinaryVersion.value match { + case "2.12" => + List("-Ywarn-unused:imports", "-Xsource:3") + case _ => Nil + } + }, + scalafmtOnCompile := { + scalaBinaryVersion.value match { + case "2.12" => true + case _ => false + } + }, + dynverSeparator := "_", // the default `+` is not compatible with docker tags ) ) @@ -47,6 +60,15 @@ lazy val `sbt-header` = .enablePlugins(AutomateHeaderPlugin, SbtPlugin) .settings(commonSettings) .settings( + headerLicense := Some( + HeaderLicense.Custom( + """|Copyright (c) 2015 - 2025, Heiko Seeberger + |Copyright (c) 2025, sbt plugin contributors + | + |SPDX-License-Identifier: Apache-2.0 + |""".stripMargin + ) + ), libraryDependencies ++= Seq( library.scalaTest % Test, ), @@ -54,6 +76,18 @@ lazy val `sbt-header` = "-Xmx1024M", s"-Dplugin.version=${version.value}", ), + (pluginCrossBuild / sbtVersion) := { + scalaBinaryVersion.value match { + case "2.12" => "1.9.9" + case _ => "2.0.0-RC4" + } + }, + scriptedSbt := { + scalaBinaryVersion.value match { + case "2.12" => "1.11.6" + case _ => (pluginCrossBuild / sbtVersion).value + } + }, ) // ***************************************************************************** @@ -76,7 +110,7 @@ lazy val commonSettings = lazy val library = new { object Version { - val scalaTest = "3.2.14" + val scalaTest = "3.2.19" } val scalaTest = "org.scalatest" %% "scalatest" % Version.scalaTest } diff --git a/project/build.properties b/project/build.properties index 1cfbe55..f0fdcab 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version = 1.7.2 +sbt.version = 1.11.6 diff --git a/project/plugins.sbt b/project/plugins.sbt index 3b3a23d..a4ef30e 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,3 +1,3 @@ -addSbtPlugin("com.github.sbt" % "sbt-ci-release" % "1.5.11") -addSbtPlugin("de.heikoseeberger" % "sbt-header" % "5.7.0") -addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.4.6") +addSbtPlugin("com.github.sbt" % "sbt-ci-release" % "1.11.2") +addSbtPlugin("de.heikoseeberger" % "sbt-header" % "5.10.0") +addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.5.5") diff --git a/src/main/scala/de/heikoseeberger/sbtheader/LicenseDetection.scala b/src/main/scala-2.12/LicenseDetection.scala similarity index 60% rename from src/main/scala/de/heikoseeberger/sbtheader/LicenseDetection.scala rename to src/main/scala-2.12/LicenseDetection.scala index d24b9d8..6e78af2 100644 --- a/src/main/scala/de/heikoseeberger/sbtheader/LicenseDetection.scala +++ b/src/main/scala-2.12/LicenseDetection.scala @@ -1,28 +1,18 @@ /* - * Copyright 2015 Heiko Seeberger + * Copyright (c) 2015 - 2025, Heiko Seeberger + * Copyright (c) 2025, sbt plugin contributors * - * 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. + * SPDX-License-Identifier: Apache-2.0 */ -package de.heikoseeberger.sbtheader +package sbtheader import sbt.URL -import scala.collection.breakOut object LicenseDetection { - private val spdxMapping = - License.spdxLicenses.map(l => (l.spdxIdentifier, l))(breakOut): Map[String, SpdxLicense] + private val spdxMapping: Map[String, SpdxLicense] = + License.spdxLicenses.iterator.map(l => (l.spdxIdentifier, l)).toMap def apply( licenses: Seq[(String, URL)], diff --git a/src/main/scala-2.12/PluginCompat.scala b/src/main/scala-2.12/PluginCompat.scala new file mode 100644 index 0000000..ebc9966 --- /dev/null +++ b/src/main/scala-2.12/PluginCompat.scala @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2015 - 2025, Heiko Seeberger + * Copyright (c) 2025, sbt plugin contributors + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package sbtheader + +import sbt.{ *, given } + +object PluginCompat { + type LicenseRef = (String, URL) + + def mkLicense(spdxId: String, uri: URL) = (spdxId, uri) + + // This adds `Def.uncached(...)` + implicit class DefOp(singleton: Def.type) { + def uncached[A1](a: A1): A1 = a + } +} diff --git a/src/main/scala-3/LicenseDetection.scala b/src/main/scala-3/LicenseDetection.scala new file mode 100644 index 0000000..4b7973a --- /dev/null +++ b/src/main/scala-3/LicenseDetection.scala @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2015 - 2025, Heiko Seeberger + * Copyright (c) 2025, sbt plugin contributors + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package sbtheader + +import sbt.URL + +object LicenseDetection: + + private val spdxMapping: Map[String, SpdxLicense] = + License.spdxLicenses.iterator.map(l => (l.spdxIdentifier, l)).toMap + + def apply( + licenses: Seq[sbt.License], + organizationName: String, + startYear: Option[String], + licenseStyle: LicenseStyle = LicenseStyle.Detailed + ): Option[License] = + apply(licenses, organizationName, startYear.map(_.toInt), None, licenseStyle) + + def apply( + licenses: Seq[sbt.License], + organizationName: String, + startYear: Option[Int], + endYear: Option[Int], + licenseStyle: LicenseStyle + ): Option[License] = + val spdxIds = + licenses match + case l :: Nil => Some(l.spdxId) + case _ => None + for + spdxId <- spdxIds + license <- spdxMapping.get(spdxId) + year <- combineYears(startYear, endYear) + yield license(year, organizationName, licenseStyle) + + private def combineYears(startYear: Option[Int], endYear: Option[Int]): Option[String] = + (startYear, endYear) match + case (Some(start), Some(end)) if start < end => Some(s"$start-$end") + case (Some(start), _) => Some(start.toString) + case (None, _) => None +end LicenseDetection diff --git a/src/main/scala-3/PluginCompat.scala b/src/main/scala-3/PluginCompat.scala new file mode 100644 index 0000000..02b0112 --- /dev/null +++ b/src/main/scala-3/PluginCompat.scala @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2015 - 2025, Heiko Seeberger + * Copyright (c) 2025, sbt plugin contributors + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package sbtheader + +import sbt.{ *, given } + +object PluginCompat: + type LicenseRef = License + + def mkLicense(spdxId: String, uri: URI): License = License(spdxId, uri) + val Apache2 = License.Apache2 + val MIT = License.MIT +end PluginCompat diff --git a/src/main/scala/de/heikoseeberger/sbtheader/AutomateHeaderPlugin.scala b/src/main/scala/de/heikoseeberger/sbtheader/AutomateHeaderPlugin.scala deleted file mode 100644 index 8f741cd..0000000 --- a/src/main/scala/de/heikoseeberger/sbtheader/AutomateHeaderPlugin.scala +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2015 Heiko Seeberger - * - * 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. - */ - -package de.heikoseeberger.sbtheader - -import sbt.{ AutoPlugin, Compile, Configuration, Def, Plugins, Setting, Test, inConfig } -import sbt.Keys.compile - -/** - * Enable this plugin to automate header creation/update on compile. By default the `Compile` and - * `Test` configurations are considered; use - * [[AutomateHeaderPlugin.autoImport.automateHeaderSettings]] to add further ones. - */ -object AutomateHeaderPlugin extends AutoPlugin { - - final object autoImport { - - def automateHeaderSettings(configurations: Configuration*): Seq[Setting[_]] = - configurations.foldLeft(List.empty[Setting[_]]) { - _ ++ inConfig(_)(compile := compile.dependsOn(HeaderPlugin.autoImport.headerCreate).value) - } - } - - override def requires: Plugins = - HeaderPlugin - - override def projectSettings: Seq[Def.Setting[_]] = - autoImport.automateHeaderSettings(Compile, Test) -} diff --git a/src/main/scala/de/heikoseeberger/sbtheader/FileType.scala b/src/main/scala/de/heikoseeberger/sbtheader/FileType.scala deleted file mode 100644 index 3592bcf..0000000 --- a/src/main/scala/de/heikoseeberger/sbtheader/FileType.scala +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2015 Heiko Seeberger - * - * 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. - */ - -package de.heikoseeberger.sbtheader - -import scala.util.matching.Regex - -final case class FileType( - extension: String, - firstLinePattern: Option[Regex] = None, - name: String = "" -) - -object FileType { - - val conf: FileType = - FileType("conf") - - val java: FileType = - FileType("java") - - val scala: FileType = - FileType("scala") - - val sh: FileType = - FileType("sh", Some(firstLinePattern("#!.*"))) - - val xml: FileType = - FileType("xml", Some(firstLinePattern("<\\?xml.*\\?>"))) - - private def firstLinePattern(firstLinePattern: String) = - s"""($firstLinePattern(?:\\s+))([\\S\\s]*)""".r -} diff --git a/src/main/scala/de/heikoseeberger/sbtheader/LicenseStyle.scala b/src/main/scala/de/heikoseeberger/sbtheader/LicenseStyle.scala deleted file mode 100644 index 7af766f..0000000 --- a/src/main/scala/de/heikoseeberger/sbtheader/LicenseStyle.scala +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright 2015 Heiko Seeberger - * - * 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. - */ - -package de.heikoseeberger.sbtheader - -sealed trait LicenseStyle - -object LicenseStyle { - final case object Detailed extends LicenseStyle - final case object SpdxSyntax extends LicenseStyle -} diff --git a/src/main/scala/sbtheader/AutomateHeaderPlugin.scala b/src/main/scala/sbtheader/AutomateHeaderPlugin.scala new file mode 100644 index 0000000..3aeed54 --- /dev/null +++ b/src/main/scala/sbtheader/AutomateHeaderPlugin.scala @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2015 - 2025, Heiko Seeberger + * Copyright (c) 2025, sbt plugin contributors + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package sbtheader + +import sbt.{ *, given } +import sbt.Keys.compile +import PluginCompat.{ *, given } + +/** + * Enable this plugin to automate header creation/update on compile. By default the `Compile` and + * `Test` configurations are considered; use + * [[AutomateHeaderPlugin.autoImport.automateHeaderSettings]] to add further ones. + */ +object AutomateHeaderPlugin extends AutoPlugin { + + object autoImport { + + def automateHeaderSettings(configurations: Configuration*): Seq[Setting[?]] = + configurations.foldLeft(List.empty[Setting[?]]) { + _ ++ inConfig(_)( + compile := Def.uncached { + compile.dependsOn(HeaderPlugin.autoImport.headerCreate).value + } + ) + } + } + + override def requires: Plugins = + HeaderPlugin + + override def projectSettings: Seq[Def.Setting[?]] = + autoImport.automateHeaderSettings(Compile, Test) +} diff --git a/src/main/scala/de/heikoseeberger/sbtheader/CommentStyle.scala b/src/main/scala/sbtheader/CommentStyle.scala similarity index 82% rename from src/main/scala/de/heikoseeberger/sbtheader/CommentStyle.scala rename to src/main/scala/sbtheader/CommentStyle.scala index 276dfa0..6db88bd 100644 --- a/src/main/scala/de/heikoseeberger/sbtheader/CommentStyle.scala +++ b/src/main/scala/sbtheader/CommentStyle.scala @@ -1,25 +1,13 @@ /* - * Copyright 2015 Heiko Seeberger + * Copyright (c) 2015 - 2025, Heiko Seeberger + * Copyright (c) 2025, sbt plugin contributors * - * 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. + * SPDX-License-Identifier: Apache-2.0 */ -package de.heikoseeberger.sbtheader +package sbtheader -import de.heikoseeberger.sbtheader.HeaderPlugin.autoImport.HeaderPattern.{ - commentBetween, - commentStartingWith -} +import sbtheader.HeaderPlugin.autoImport.HeaderPattern.{ commentBetween, commentStartingWith } import scala.util.matching.Regex /** @@ -104,7 +92,7 @@ final class LineCommentCreator(linePrefix: String, lineSuffix: String = "") exte } def appendLineSuffix(s: String) = s match { - case "" => "" + case "" => "" case line => // Only add the suffix when a prefix was added before if (linePrefix.trim.nonEmpty && lineSuffix.trim.nonEmpty) s"$line $lineSuffix" else line } diff --git a/src/main/scala/sbtheader/FileType.scala b/src/main/scala/sbtheader/FileType.scala new file mode 100644 index 0000000..6cfe2ae --- /dev/null +++ b/src/main/scala/sbtheader/FileType.scala @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2015 - 2025, Heiko Seeberger + * Copyright (c) 2025, sbt plugin contributors + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package sbtheader + +import scala.util.matching.Regex + +final case class FileType( + extension: String, + firstLinePattern: Option[Regex] = None, + name: String = "" +) + +object FileType { + + val conf: FileType = + FileType("conf") + + val java: FileType = + FileType("java") + + val scala: FileType = + FileType("scala") + + val sh: FileType = + FileType("sh", Some(firstLinePattern("#!.*"))) + + val xml: FileType = + FileType("xml", Some(firstLinePattern("<\\?xml.*\\?>"))) + + private def firstLinePattern(firstLinePattern: String) = + s"""($firstLinePattern(?:\\s+))([\\S\\s]*)""".r +} diff --git a/src/main/scala/de/heikoseeberger/sbtheader/HeaderCreator.scala b/src/main/scala/sbtheader/HeaderCreator.scala similarity index 72% rename from src/main/scala/de/heikoseeberger/sbtheader/HeaderCreator.scala rename to src/main/scala/sbtheader/HeaderCreator.scala index 534905d..ddd616b 100644 --- a/src/main/scala/de/heikoseeberger/sbtheader/HeaderCreator.scala +++ b/src/main/scala/sbtheader/HeaderCreator.scala @@ -1,20 +1,11 @@ /* - * Copyright 2015 Heiko Seeberger + * Copyright (c) 2015 - 2025, Heiko Seeberger + * Copyright (c) 2025, sbt plugin contributors * - * 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. + * SPDX-License-Identifier: Apache-2.0 */ -package de.heikoseeberger.sbtheader +package sbtheader import java.io.InputStream import sbt.Logger @@ -25,7 +16,7 @@ object HeaderCreator { def apply( fileType: FileType, commentStyle: CommentStyle, - license: License, + license: sbtheader.License, headerEmptyLine: Boolean, log: Logger, input: InputStream @@ -36,7 +27,7 @@ object HeaderCreator { final class HeaderCreator private ( fileType: FileType, commentStyle: CommentStyle, - license: License, + license: sbtheader.License, headerEmptyLine: Boolean, log: Logger, input: InputStream @@ -47,7 +38,7 @@ final class HeaderCreator private ( private val (firstLine, text) = { val fileContent = - try scala.io.Source.fromInputStream(input)(Codec.UTF8).mkString + try scala.io.Source.fromInputStream(input)(using Codec.UTF8).mkString finally input.close() fileType.firstLinePattern match { diff --git a/src/main/scala/de/heikoseeberger/sbtheader/HeaderPlugin.scala b/src/main/scala/sbtheader/HeaderPlugin.scala similarity index 74% rename from src/main/scala/de/heikoseeberger/sbtheader/HeaderPlugin.scala rename to src/main/scala/sbtheader/HeaderPlugin.scala index 900a1f2..d8c8b06 100644 --- a/src/main/scala/de/heikoseeberger/sbtheader/HeaderPlugin.scala +++ b/src/main/scala/sbtheader/HeaderPlugin.scala @@ -1,40 +1,16 @@ /* - * Copyright 2015 Heiko Seeberger + * Copyright (c) 2015 - 2025, Heiko Seeberger + * Copyright (c) 2025, sbt plugin contributors * - * 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. + * SPDX-License-Identifier: Apache-2.0 */ -package de.heikoseeberger.sbtheader +package sbtheader -import de.heikoseeberger.sbtheader.CommentStyle.cStyleBlockComment +import sbtheader.CommentStyle.cStyleBlockComment import java.nio.charset.StandardCharsets.UTF_8 import java.nio.file.Files -import sbt.{ - AutoPlugin, - Compile, - Configuration, - File, - Logger, - ScopeFilter, - Setting, - SettingKey, - TaskKey, - Test, - inAnyConfiguration, - inConfig, - settingKey, - taskKey -} +import sbt.{ *, given } import sbt.Defaults.collectFiles import sbt.Keys._ import sbt.internal.util.MessageOnlyException @@ -44,13 +20,13 @@ import scala.util.matching.Regex object HeaderPlugin extends AutoPlugin { - final object autoImport { + object autoImport { - val HeaderLicense = License + val HeaderLicense = sbtheader.License val HeaderLicenseStyle = LicenseStyle - final object HeaderPattern { + object HeaderPattern { def commentBetween(start: String, middle: String, end: String): Regex = raw"""(?s)($start(?!\$middle).*?$end(?:\n|\r|\r\n)+)(.*)""".r @@ -68,11 +44,16 @@ object HeaderPlugin extends AutoPlugin { "The end of the range of years to specify in the header. Defaults to None (only the `startYear` is used)." ) - val headerLicense: SettingKey[Option[License]] = + val headerLicense: SettingKey[Option[sbtheader.License]] = settingKey( "The license to apply to files; None by default (enabling auto detection from project settings)" ) + val headerLicenseFallback: SettingKey[Option[sbtheader.License]] = + settingKey( + "The license crated by auto detection from the project settings" + ) + val headerLicenseStyle: SettingKey[LicenseStyle] = settingKey[LicenseStyle] { "The license style to be used. Can be `Detailed` or `SpdxSyntax`. Defaults to Detailed." @@ -87,25 +68,29 @@ object HeaderPlugin extends AutoPlugin { settingKey("If an empty line header should be added between the header and the body") val headerSources = - taskKey[scala.collection.Seq[File]]("Sources which need headers checked or created.") + taskKey[scala.Seq[File]]("Sources which need headers checked or created.") val headerResources = - taskKey[scala.collection.Seq[File]]("Resources which need headers checked or created.") + taskKey[scala.Seq[File]]("Resources which need headers checked or created.") + @transient val headerCreate: TaskKey[Iterable[File]] = taskKey[Iterable[File]]("Create/update headers") + @transient val headerCreateAll: TaskKey[Iterable[File]] = taskKey[Iterable[File]]("Create/update headers in all configurations") + @transient val headerCheck: TaskKey[Iterable[File]] = taskKey[Iterable[File]]("Check whether files have headers") + @transient val headerCheckAll: TaskKey[Iterable[File]] = taskKey[Iterable[File]]("Check whether files have headers in all configurations") - def headerSettings(configurations: Configuration*): Seq[Setting[_]] = - configurations.foldLeft(List.empty[Setting[_]])(_ ++ inConfig(_)(toBeScopedSettings)) + def headerSettings(configurations: Configuration*): Seq[Setting[?]] = + configurations.foldLeft(List.empty[Setting[?]])(_ ++ inConfig(_)(toBeScopedSettings)) } import autoImport._ @@ -114,7 +99,16 @@ object HeaderPlugin extends AutoPlugin { override def requires = JvmPlugin - override def globalSettings = Vector(headerEmptyLine := true) + override def globalSettings = Vector( + headerEmptyLine := true, + headerEndYear := None, + headerLicenseStyle := LicenseStyle.Detailed, + headerMappings := Map( + FileType.scala -> cStyleBlockComment, + FileType.java -> cStyleBlockComment + ), + headerLicense := None, + ) override def projectSettings = notToBeScopedSettings ++ headerSettings(Compile, Test) @@ -130,26 +124,36 @@ object HeaderPlugin extends AutoPlugin { headerResources / includeFilter, headerResources / excludeFilter ).value, - headerCreate := createHeadersTask( - streams.value.cacheDirectory, - headerSources.value.toList ++ - headerResources.value.toList, - headerLicense.value.getOrElse(sys.error("Unable to auto detect project license")), - headerMappings.value, - headerEmptyLine.value, - streams.value.log - ), + headerCreate := { + val fallback = headerLicenseFallback.value + createHeadersTask( + streams.value.cacheDirectory, + headerSources.value.toList ++ + headerResources.value.toList, + headerLicense.value + .orElse(fallback) + .getOrElse(sys.error("Unable to auto detect project license")), + headerMappings.value, + headerEmptyLine.value, + streams.value.log + ) + }, headerCreateAll := headerCreate.?.all( ScopeFilter(configurations = inAnyConfiguration) ).value.flatten.flatten.toSet, - headerCheck := checkHeadersTask( - headerSources.value.toList ++ - headerResources.value.toList, - headerLicense.value.getOrElse(sys.error("Unable to auto detect project license")), - headerMappings.value, - headerEmptyLine.value, - streams.value.log - ), + headerCheck := { + val fallback = headerLicenseFallback.value + checkHeadersTask( + headerSources.value.toList ++ + headerResources.value.toList, + headerLicense.value + .orElse(fallback) + .getOrElse(sys.error("Unable to auto detect project license")), + headerMappings.value, + headerEmptyLine.value, + streams.value.log + ) + }, headerCheckAll := headerCheck.?.all( ScopeFilter(configurations = inAnyConfiguration) ).value.flatten.flatten.toSet @@ -157,19 +161,13 @@ object HeaderPlugin extends AutoPlugin { private def notToBeScopedSettings = Vector( - headerMappings := Map( - FileType.scala -> cStyleBlockComment, - FileType.java -> cStyleBlockComment - ), - headerLicense := LicenseDetection( + headerLicenseFallback := LicenseDetection( licenses.value.toList, organizationName.value, startYear.value, headerEndYear.value, headerLicenseStyle.value ), - headerEndYear := None, - headerLicenseStyle := LicenseStyle.Detailed, headerSources / includeFilter := (unmanagedSources / includeFilter).value, headerSources / excludeFilter := (unmanagedSources / excludeFilter).value, headerResources / includeFilter := (unmanagedResources / includeFilter).value, @@ -179,7 +177,7 @@ object HeaderPlugin extends AutoPlugin { private def createHeadersTask( cacheDirectory: File, files: Seq[File], - headerLicense: License, + headerLicense: sbtheader.License, headerMappings: Map[FileType, CommentStyle], headerEmptyLine: Boolean, log: Logger @@ -192,7 +190,7 @@ object HeaderPlugin extends AutoPlugin { private def createHeaders( files: Set[File], - headerLicense: License, + headerLicense: sbtheader.License, headerMappings: Map[FileType, CommentStyle], headerEmptyLine: Boolean, log: Logger @@ -224,7 +222,7 @@ object HeaderPlugin extends AutoPlugin { private def checkHeadersTask( files: Seq[File], - headerLicense: License, + headerLicense: sbtheader.License, headerMappings: Map[FileType, CommentStyle], headerEmptyLine: Boolean, log: Logger diff --git a/src/main/scala/de/heikoseeberger/sbtheader/License.scala b/src/main/scala/sbtheader/License.scala similarity index 96% rename from src/main/scala/de/heikoseeberger/sbtheader/License.scala rename to src/main/scala/sbtheader/License.scala index 36d4f44..8e8062a 100644 --- a/src/main/scala/de/heikoseeberger/sbtheader/License.scala +++ b/src/main/scala/sbtheader/License.scala @@ -1,22 +1,13 @@ /* - * Copyright 2015 Heiko Seeberger + * Copyright (c) 2015 - 2025, Heiko Seeberger + * Copyright (c) 2025, sbt plugin contributors * - * 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. + * SPDX-License-Identifier: Apache-2.0 */ -package de.heikoseeberger.sbtheader +package sbtheader -import de.heikoseeberger.sbtheader.LicenseStyle.{ Detailed, SpdxSyntax } +import sbtheader.LicenseStyle.{ Detailed, SpdxSyntax } sealed trait License { def text: String @@ -161,7 +152,7 @@ object License { } } - final object MPLv2_NoCopyright extends License { + object MPLv2_NoCopyright extends License { override val text: String = s"""|This Source Code Form is subject to the terms of the Mozilla Public diff --git a/src/main/scala/sbtheader/LicenseStyle.scala b/src/main/scala/sbtheader/LicenseStyle.scala new file mode 100644 index 0000000..72bb308 --- /dev/null +++ b/src/main/scala/sbtheader/LicenseStyle.scala @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2015 - 2025, Heiko Seeberger + * Copyright (c) 2025, sbt plugin contributors + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package sbtheader + +sealed trait LicenseStyle + +object LicenseStyle { + final case object Detailed extends LicenseStyle + final case object SpdxSyntax extends LicenseStyle +} diff --git a/src/main/scala/de/heikoseeberger/sbtheader/package.scala b/src/main/scala/sbtheader/package.scala similarity index 51% rename from src/main/scala/de/heikoseeberger/sbtheader/package.scala rename to src/main/scala/sbtheader/package.scala index ac9b579..a4421e7 100644 --- a/src/main/scala/de/heikoseeberger/sbtheader/package.scala +++ b/src/main/scala/sbtheader/package.scala @@ -1,21 +1,10 @@ /* - * Copyright 2015 Heiko Seeberger + * Copyright (c) 2015 - 2025, Heiko Seeberger + * Copyright (c) 2025, sbt plugin contributors * - * 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. + * SPDX-License-Identifier: Apache-2.0 */ -package de.heikoseeberger - import java.io.File import scala.util.matching.Regex @@ -34,7 +23,7 @@ package object sbtheader { } } - private final object FileOps { + private object FileOps { val extensionPattern: Regex = """.+\.(.+)""".r } diff --git a/src/sbt-test/sbt-header/auto-detection-end-year/project/test.sbt b/src/sbt-test/sbt-header/auto-detection-end-year/project/test.sbt index 07e628c..856d7fa 100644 --- a/src/sbt-test/sbt-header/auto-detection-end-year/project/test.sbt +++ b/src/sbt-test/sbt-header/auto-detection-end-year/project/test.sbt @@ -3,4 +3,4 @@ val pluginVersion = .get("plugin.version") .getOrElse(sys.error("Sys prop plugin.version must be defined!")) -addSbtPlugin("de.heikoseeberger" % "sbt-header" % pluginVersion) +addSbtPlugin("com.github.sbt" % "sbt-header" % pluginVersion) diff --git a/src/sbt-test/sbt-header/auto-detection-end-year/test.sbt b/src/sbt-test/sbt-header/auto-detection-end-year/test.sbt index a2de471..1134829 100644 --- a/src/sbt-test/sbt-header/auto-detection-end-year/test.sbt +++ b/src/sbt-test/sbt-header/auto-detection-end-year/test.sbt @@ -1,7 +1,7 @@ organizationName := "Heiko Seeberger" startYear := Some(2015) headerEndYear := Some(2022) -licenses := List(("Apache-2.0", new URL("https://www.apache.org/licenses/LICENSE-2.0.txt"))) +licenses := List(("Apache-2.0", url("https://www.apache.org/licenses/LICENSE-2.0.txt"))) val checkFileContents = taskKey[Unit]("Verify file contents match expected contents") @@ -9,8 +9,8 @@ checkFileContents := { checkFile("HasNoHeader.scala") def checkFile(name: String) = { - val actualPath = (scalaSource.in(Compile).value / name).toString - val expectedPath = (resourceDirectory.in(Compile).value / s"${name}_expected").toString + val actualPath = ((Compile / scalaSource).value / name).toString + val expectedPath = ((Compile / resourceDirectory).value / s"${name}_expected").toString val actual = scala.io.Source.fromFile(actualPath).mkString val expected = scala.io.Source.fromFile(expectedPath).mkString diff --git a/src/sbt-test/sbt-header/auto-detection-with-different-style/project/test.sbt b/src/sbt-test/sbt-header/auto-detection-with-different-style/project/test.sbt index 07e628c..856d7fa 100644 --- a/src/sbt-test/sbt-header/auto-detection-with-different-style/project/test.sbt +++ b/src/sbt-test/sbt-header/auto-detection-with-different-style/project/test.sbt @@ -3,4 +3,4 @@ val pluginVersion = .get("plugin.version") .getOrElse(sys.error("Sys prop plugin.version must be defined!")) -addSbtPlugin("de.heikoseeberger" % "sbt-header" % pluginVersion) +addSbtPlugin("com.github.sbt" % "sbt-header" % pluginVersion) diff --git a/src/sbt-test/sbt-header/auto-detection-with-different-style/test.sbt b/src/sbt-test/sbt-header/auto-detection-with-different-style/test.sbt index 76d502a..f0defce 100644 --- a/src/sbt-test/sbt-header/auto-detection-with-different-style/test.sbt +++ b/src/sbt-test/sbt-header/auto-detection-with-different-style/test.sbt @@ -1,4 +1,4 @@ -organizationName := "Heiko Seeberger" -startYear := Some(2015) -licenses := List(("Apache-2.0", new URL("https://www.apache.org/licenses/LICENSE-2.0.txt"))) +organizationName := "Heiko Seeberger" +startYear := Some(2015) +licenses := List(("Apache-2.0", url("https://www.apache.org/licenses/LICENSE-2.0.txt"))) headerLicenseStyle := HeaderLicenseStyle.SpdxSyntax diff --git a/src/sbt-test/sbt-header/auto-detection/project/test.sbt b/src/sbt-test/sbt-header/auto-detection/project/test.sbt index 07e628c..856d7fa 100644 --- a/src/sbt-test/sbt-header/auto-detection/project/test.sbt +++ b/src/sbt-test/sbt-header/auto-detection/project/test.sbt @@ -3,4 +3,4 @@ val pluginVersion = .get("plugin.version") .getOrElse(sys.error("Sys prop plugin.version must be defined!")) -addSbtPlugin("de.heikoseeberger" % "sbt-header" % pluginVersion) +addSbtPlugin("com.github.sbt" % "sbt-header" % pluginVersion) diff --git a/src/sbt-test/sbt-header/auto-detection/test.sbt b/src/sbt-test/sbt-header/auto-detection/test.sbt index cbfa2a6..ebe5a11 100644 --- a/src/sbt-test/sbt-header/auto-detection/test.sbt +++ b/src/sbt-test/sbt-header/auto-detection/test.sbt @@ -1,6 +1,6 @@ organizationName := "Heiko Seeberger" startYear := Some(2015) -licenses := List(("Apache-2.0", new URL("https://www.apache.org/licenses/LICENSE-2.0.txt"))) +licenses := List(("Apache-2.0", url("https://www.apache.org/licenses/LICENSE-2.0.txt"))) val checkFileContents = taskKey[Unit]("Verify file contents match expected contents") @@ -8,8 +8,8 @@ checkFileContents := { checkFile("HasNoHeader.scala") def checkFile(name: String) = { - val actualPath = (scalaSource.in(Compile).value / name).toString - val expectedPath = (resourceDirectory.in(Compile).value / s"${name}_expected").toString + val actualPath = ((Compile / scalaSource).value / name).toString + val expectedPath = ((Compile / resourceDirectory).value / s"${name}_expected").toString val actual = scala.io.Source.fromFile(actualPath).mkString val expected = scala.io.Source.fromFile(expectedPath).mkString diff --git a/src/sbt-test/sbt-header/checkHeaders-all/test b/src/sbt-test/sbt-header/checkHeaders-all/disabled similarity index 100% rename from src/sbt-test/sbt-header/checkHeaders-all/test rename to src/sbt-test/sbt-header/checkHeaders-all/disabled diff --git a/src/sbt-test/sbt-header/checkHeaders-all/project/test.sbt b/src/sbt-test/sbt-header/checkHeaders-all/project/test.sbt index 6d337f1..654af30 100644 --- a/src/sbt-test/sbt-header/checkHeaders-all/project/test.sbt +++ b/src/sbt-test/sbt-header/checkHeaders-all/project/test.sbt @@ -2,4 +2,4 @@ val pluginVersion = sys.props .get("plugin.version") .getOrElse(sys.error("Sys prop plugin.version must be defined!")) -addSbtPlugin("de.heikoseeberger" % "sbt-header" % pluginVersion) +addSbtPlugin("com.github.sbt" % "sbt-header" % pluginVersion) diff --git a/src/sbt-test/sbt-header/checkHeaders-all/test.sbt b/src/sbt-test/sbt-header/checkHeaders-all/test.sbt index ca57d7a..4aec1e2 100644 --- a/src/sbt-test/sbt-header/checkHeaders-all/test.sbt +++ b/src/sbt-test/sbt-header/checkHeaders-all/test.sbt @@ -1,5 +1,5 @@ lazy val root = (project in file(".")) .configs(IntegrationTest) .settings(Defaults.itSettings) - .settings(headerSettings(IntegrationTest): _*) + .settings(headerSettings(IntegrationTest)*) .settings(headerLicense := Some(HeaderLicense.ALv2("2015", "Heiko Seeberger"))) diff --git a/src/sbt-test/sbt-header/checkHeaders-fails-all/test b/src/sbt-test/sbt-header/checkHeaders-fails-all/disabled similarity index 100% rename from src/sbt-test/sbt-header/checkHeaders-fails-all/test rename to src/sbt-test/sbt-header/checkHeaders-fails-all/disabled diff --git a/src/sbt-test/sbt-header/checkHeaders-fails-all/project/test.sbt b/src/sbt-test/sbt-header/checkHeaders-fails-all/project/test.sbt index 6d337f1..654af30 100644 --- a/src/sbt-test/sbt-header/checkHeaders-fails-all/project/test.sbt +++ b/src/sbt-test/sbt-header/checkHeaders-fails-all/project/test.sbt @@ -2,4 +2,4 @@ val pluginVersion = sys.props .get("plugin.version") .getOrElse(sys.error("Sys prop plugin.version must be defined!")) -addSbtPlugin("de.heikoseeberger" % "sbt-header" % pluginVersion) +addSbtPlugin("com.github.sbt" % "sbt-header" % pluginVersion) diff --git a/src/sbt-test/sbt-header/checkHeaders-fails-all/test.sbt b/src/sbt-test/sbt-header/checkHeaders-fails-all/test.sbt index ca57d7a..4aec1e2 100644 --- a/src/sbt-test/sbt-header/checkHeaders-fails-all/test.sbt +++ b/src/sbt-test/sbt-header/checkHeaders-fails-all/test.sbt @@ -1,5 +1,5 @@ lazy val root = (project in file(".")) .configs(IntegrationTest) .settings(Defaults.itSettings) - .settings(headerSettings(IntegrationTest): _*) + .settings(headerSettings(IntegrationTest)*) .settings(headerLicense := Some(HeaderLicense.ALv2("2015", "Heiko Seeberger"))) diff --git a/src/sbt-test/sbt-header/checkHeaders-fails/project/test.sbt b/src/sbt-test/sbt-header/checkHeaders-fails/project/test.sbt index 6d337f1..654af30 100644 --- a/src/sbt-test/sbt-header/checkHeaders-fails/project/test.sbt +++ b/src/sbt-test/sbt-header/checkHeaders-fails/project/test.sbt @@ -2,4 +2,4 @@ val pluginVersion = sys.props .get("plugin.version") .getOrElse(sys.error("Sys prop plugin.version must be defined!")) -addSbtPlugin("de.heikoseeberger" % "sbt-header" % pluginVersion) +addSbtPlugin("com.github.sbt" % "sbt-header" % pluginVersion) diff --git a/src/sbt-test/sbt-header/checkHeaders/project/test.sbt b/src/sbt-test/sbt-header/checkHeaders/project/test.sbt index 6d337f1..654af30 100644 --- a/src/sbt-test/sbt-header/checkHeaders/project/test.sbt +++ b/src/sbt-test/sbt-header/checkHeaders/project/test.sbt @@ -2,4 +2,4 @@ val pluginVersion = sys.props .get("plugin.version") .getOrElse(sys.error("Sys prop plugin.version must be defined!")) -addSbtPlugin("de.heikoseeberger" % "sbt-header" % pluginVersion) +addSbtPlugin("com.github.sbt" % "sbt-header" % pluginVersion) diff --git a/src/sbt-test/sbt-header/custom-license/project/test.sbt b/src/sbt-test/sbt-header/custom-license/project/test.sbt index 07e628c..856d7fa 100644 --- a/src/sbt-test/sbt-header/custom-license/project/test.sbt +++ b/src/sbt-test/sbt-header/custom-license/project/test.sbt @@ -3,4 +3,4 @@ val pluginVersion = .get("plugin.version") .getOrElse(sys.error("Sys prop plugin.version must be defined!")) -addSbtPlugin("de.heikoseeberger" % "sbt-header" % pluginVersion) +addSbtPlugin("com.github.sbt" % "sbt-header" % pluginVersion) diff --git a/src/sbt-test/sbt-header/custom-license/test.sbt b/src/sbt-test/sbt-header/custom-license/test.sbt index 61768c2..aa2c444 100644 --- a/src/sbt-test/sbt-header/custom-license/test.sbt +++ b/src/sbt-test/sbt-header/custom-license/test.sbt @@ -14,8 +14,8 @@ checkFileContents := { checkFile("HasNoHeader.scala") def checkFile(name: String) = { - val actualPath = (scalaSource.in(Compile).value / name).toString - val expectedPath = (resourceDirectory.in(Compile).value / s"${name}_expected").toString + val actualPath = ((Compile / scalaSource).value / name).toString + val expectedPath = ((Compile / resourceDirectory).value / s"${name}_expected").toString val actual = scala.io.Source.fromFile(actualPath).mkString val expected = scala.io.Source.fromFile(expectedPath).mkString diff --git a/src/sbt-test/sbt-header/excludes/project/test.sbt b/src/sbt-test/sbt-header/excludes/project/test.sbt index 6d337f1..654af30 100644 --- a/src/sbt-test/sbt-header/excludes/project/test.sbt +++ b/src/sbt-test/sbt-header/excludes/project/test.sbt @@ -2,4 +2,4 @@ val pluginVersion = sys.props .get("plugin.version") .getOrElse(sys.error("Sys prop plugin.version must be defined!")) -addSbtPlugin("de.heikoseeberger" % "sbt-header" % pluginVersion) +addSbtPlugin("com.github.sbt" % "sbt-header" % pluginVersion) diff --git a/src/sbt-test/sbt-header/excludes/test.sbt b/src/sbt-test/sbt-header/excludes/test.sbt index 6782d70..60639ef 100644 --- a/src/sbt-test/sbt-header/excludes/test.sbt +++ b/src/sbt-test/sbt-header/excludes/test.sbt @@ -1,25 +1,25 @@ headerLicense := Some(HeaderLicense.ALv2("2015", "Heiko Seeberger")) -excludeFilter.in(headerSources) := HiddenFileFilter || "*Excluded.scala" +headerSources / excludeFilter := HiddenFileFilter || "*Excluded.scala" val checkFiles = taskKey[Unit]("Verify files match expected files") checkFiles := { val includeFiles = Seq( - (scalaSource.in(Compile).value / "Included.scala").toString, - (scalaSource.in(Compile).value / "de/heikoseeberger/allincluded/Included.scala").toString, - (scalaSource.in(Compile).value / "de/heikoseeberger/mixed/Included.scala").toString + ((Compile / scalaSource).value / "Included.scala").toString, + ((Compile / scalaSource).value / "de/heikoseeberger/allincluded/Included.scala").toString, + ((Compile / scalaSource).value / "de/heikoseeberger/mixed/Included.scala").toString ) val excludeFiles = Seq( - (scalaSource.in(Compile).value / "Excluded.scala").toString, - (scalaSource.in(Compile).value / "de/heikoseeberger/allexcluded/Excluded.scala").toString, - (scalaSource.in(Compile).value / "de/heikoseeberger/mixed/Excluded.scala").toString + ((Compile / scalaSource).value / "Excluded.scala").toString, + ((Compile / scalaSource).value / "de/heikoseeberger/allexcluded/Excluded.scala").toString, + ((Compile / scalaSource).value / "de/heikoseeberger/mixed/Excluded.scala").toString ) // Check list of source files to process - val nonHeaderCreateSources = unmanagedSources.in(Compile).value - val headerCreateSources = headerSources.in(Compile).value + val nonHeaderCreateSources = (Compile / unmanagedSources).value + val headerCreateSources = (Compile / headerSources).value def assertPathSetEquality(a: Seq[File], b: Seq[File], failureMessage: String): Unit = { val aSet = a.map(_.getCanonicalPath).toSet @@ -51,9 +51,9 @@ checkFiles := { // Check contents of files val expectedExcludedFile = - (resourceDirectory.in(Compile).value / "Excluded.scala_expected").toString + ((Compile / resourceDirectory).value / "Excluded.scala_expected").toString val expectedIncludedFile = - (resourceDirectory.in(Compile).value / "Included.scala_expected").toString + ((Compile / resourceDirectory).value / "Included.scala_expected").toString checkFileContents(excludeFiles, expectedExcludedFile) checkFileContents(includeFiles, expectedIncludedFile) diff --git a/src/sbt-test/sbt-header/header-style/project/test.sbt b/src/sbt-test/sbt-header/header-style/project/test.sbt index 07e628c..856d7fa 100644 --- a/src/sbt-test/sbt-header/header-style/project/test.sbt +++ b/src/sbt-test/sbt-header/header-style/project/test.sbt @@ -3,4 +3,4 @@ val pluginVersion = .get("plugin.version") .getOrElse(sys.error("Sys prop plugin.version must be defined!")) -addSbtPlugin("de.heikoseeberger" % "sbt-header" % pluginVersion) +addSbtPlugin("com.github.sbt" % "sbt-header" % pluginVersion) diff --git a/src/sbt-test/sbt-header/header-style/test.sbt b/src/sbt-test/sbt-header/header-style/test.sbt index 7bcaf2f..a294957 100644 --- a/src/sbt-test/sbt-header/header-style/test.sbt +++ b/src/sbt-test/sbt-header/header-style/test.sbt @@ -8,8 +8,8 @@ checkFileContents := { checkFile("HasNoHeader.scala") def checkFile(name: String) = { - val actualPath = (scalaSource.in(Compile).value / name).toString - val expectedPath = (resourceDirectory.in(Compile).value / s"${name}_expected").toString + val actualPath = ((Compile / scalaSource).value / name).toString + val expectedPath = ((Compile / resourceDirectory).value / s"${name}_expected").toString val actual = scala.io.Source.fromFile(actualPath).mkString val expected = scala.io.Source.fromFile(expectedPath).mkString diff --git a/src/sbt-test/sbt-header/incremental/project/test.sbt b/src/sbt-test/sbt-header/incremental/project/test.sbt index 07e628c..856d7fa 100644 --- a/src/sbt-test/sbt-header/incremental/project/test.sbt +++ b/src/sbt-test/sbt-header/incremental/project/test.sbt @@ -3,4 +3,4 @@ val pluginVersion = .get("plugin.version") .getOrElse(sys.error("Sys prop plugin.version must be defined!")) -addSbtPlugin("de.heikoseeberger" % "sbt-header" % pluginVersion) +addSbtPlugin("com.github.sbt" % "sbt-header" % pluginVersion) diff --git a/src/sbt-test/sbt-header/incremental/test.sbt b/src/sbt-test/sbt-header/incremental/test.sbt index 02be859..edcded8 100644 --- a/src/sbt-test/sbt-header/incremental/test.sbt +++ b/src/sbt-test/sbt-header/incremental/test.sbt @@ -11,8 +11,8 @@ stripHeader := { stripHeader("HasHeader.scala") def stripHeader(name: String) = { - val actualPath = (scalaSource.in(Compile).value / name).toString - val headerDropped = (resourceDirectory.in(Compile).value / s"${name}_headerdropped").toString + val actualPath = ((Compile / scalaSource).value / name).toString + val headerDropped = ((Compile / resourceDirectory).value / s"${name}_headerdropped").toString Files.delete(file(actualPath).toPath) Files.copy(file(headerDropped).toPath, file(actualPath).toPath) @@ -24,8 +24,8 @@ checkFileContents := { checkFile("HasNoHeader.scala") def checkFile(name: String) = { - val actualPath = (scalaSource.in(Compile).value / name).toString - val expectedPath = (resourceDirectory.in(Compile).value / s"${name}_expected").toString + val actualPath = ((Compile / scalaSource).value / name).toString + val expectedPath = ((Compile / resourceDirectory).value / s"${name}_expected").toString val actual = scala.io.Source.fromFile(actualPath).mkString val expected = scala.io.Source.fromFile(expectedPath).mkString @@ -41,6 +41,6 @@ checkFileContents := { } removeFile := { - val actualPath = scalaSource.in(Compile).value / "HasNoHeader.scala" + val actualPath = (Compile / scalaSource).value / "HasNoHeader.scala" Files.delete(actualPath.toPath) } diff --git a/src/sbt-test/sbt-header/no-file-extensions/project/test.sbt b/src/sbt-test/sbt-header/no-file-extensions/project/test.sbt index 07e628c..856d7fa 100644 --- a/src/sbt-test/sbt-header/no-file-extensions/project/test.sbt +++ b/src/sbt-test/sbt-header/no-file-extensions/project/test.sbt @@ -3,4 +3,4 @@ val pluginVersion = .get("plugin.version") .getOrElse(sys.error("Sys prop plugin.version must be defined!")) -addSbtPlugin("de.heikoseeberger" % "sbt-header" % pluginVersion) +addSbtPlugin("com.github.sbt" % "sbt-header" % pluginVersion) diff --git a/src/sbt-test/sbt-header/no-file-extensions/test.sbt b/src/sbt-test/sbt-header/no-file-extensions/test.sbt index f68b6df..343a635 100644 --- a/src/sbt-test/sbt-header/no-file-extensions/test.sbt +++ b/src/sbt-test/sbt-header/no-file-extensions/test.sbt @@ -1,16 +1,27 @@ headerLicense := Some(HeaderLicense.ALv2("2015", "Heiko Seeberger")) // Files named exactly "routes" (with no extension) -headerMappings := headerMappings.value + (HeaderFileType("", None, "routes") -> HeaderCommentStyle.hashLineComment) +headerMappings := headerMappings.value + (HeaderFileType( + "", + None, + "routes" +) -> HeaderCommentStyle.hashLineComment) // Files named exactly "more.routes" -headerMappings := headerMappings.value + (HeaderFileType("routes", None, "more") -> HeaderCommentStyle.cStyleBlockComment) +headerMappings := headerMappings.value + (HeaderFileType( + "routes", + None, + "more" +) -> HeaderCommentStyle.cStyleBlockComment) // Hidden files named exactly ".routes" -headerMappings := headerMappings.value + (HeaderFileType("", None, ".routes") -> HeaderCommentStyle.cppStyleLineComment) +headerMappings := headerMappings.value + (HeaderFileType( + "", + None, + ".routes" +) -> HeaderCommentStyle.cppStyleLineComment) // Do not exclude hidden files (.filename) unmanagedResources / excludeFilter := (_ => false) - val checkFileContents = taskKey[Unit]("Verify file contents match expected contents") checkFileContents := { @@ -19,8 +30,8 @@ checkFileContents := { checkFile(".routes") def checkFile(name: String) = { - val actualPath = (resourceDirectory.in(Compile).value / name).toString - val expectedPath = (resourceDirectory.in(Compile).value / s"${name}_expected").toString + val actualPath = ((Compile / resourceDirectory).value / name).toString + val expectedPath = ((Compile / resourceDirectory).value / s"${name}_expected").toString val actual = scala.io.Source.fromFile(actualPath).mkString val expected = scala.io.Source.fromFile(expectedPath).mkString diff --git a/src/sbt-test/sbt-header/override-default-mappings/project/test.sbt b/src/sbt-test/sbt-header/override-default-mappings/project/test.sbt index 07e628c..856d7fa 100644 --- a/src/sbt-test/sbt-header/override-default-mappings/project/test.sbt +++ b/src/sbt-test/sbt-header/override-default-mappings/project/test.sbt @@ -3,4 +3,4 @@ val pluginVersion = .get("plugin.version") .getOrElse(sys.error("Sys prop plugin.version must be defined!")) -addSbtPlugin("de.heikoseeberger" % "sbt-header" % pluginVersion) +addSbtPlugin("com.github.sbt" % "sbt-header" % pluginVersion) diff --git a/src/sbt-test/sbt-header/override-default-mappings/test.sbt b/src/sbt-test/sbt-header/override-default-mappings/test.sbt index 8f46b57..6f24ca8 100644 --- a/src/sbt-test/sbt-header/override-default-mappings/test.sbt +++ b/src/sbt-test/sbt-header/override-default-mappings/test.sbt @@ -8,8 +8,8 @@ checkFileContents := { checkFile("HasNoHeader.scala") def checkFile(name: String) = { - val actualPath = (scalaSource.in(Compile).value / name).toString - val expectedPath = (resourceDirectory.in(Compile).value / s"${name}_expected").toString + val actualPath = ((Compile / scalaSource).value / name).toString + val expectedPath = ((Compile / resourceDirectory).value / s"${name}_expected").toString val actual = scala.io.Source.fromFile(actualPath).mkString val expected = scala.io.Source.fromFile(expectedPath).mkString diff --git a/src/sbt-test/sbt-header/simple-all/test b/src/sbt-test/sbt-header/simple-all/disabled similarity index 100% rename from src/sbt-test/sbt-header/simple-all/test rename to src/sbt-test/sbt-header/simple-all/disabled diff --git a/src/sbt-test/sbt-header/simple-all/project/test.sbt b/src/sbt-test/sbt-header/simple-all/project/test.sbt index 07e628c..856d7fa 100644 --- a/src/sbt-test/sbt-header/simple-all/project/test.sbt +++ b/src/sbt-test/sbt-header/simple-all/project/test.sbt @@ -3,4 +3,4 @@ val pluginVersion = .get("plugin.version") .getOrElse(sys.error("Sys prop plugin.version must be defined!")) -addSbtPlugin("de.heikoseeberger" % "sbt-header" % pluginVersion) +addSbtPlugin("com.github.sbt" % "sbt-header" % pluginVersion) diff --git a/src/sbt-test/sbt-header/simple-all/test.sbt b/src/sbt-test/sbt-header/simple-all/test.sbt index ca57d7a..4aec1e2 100644 --- a/src/sbt-test/sbt-header/simple-all/test.sbt +++ b/src/sbt-test/sbt-header/simple-all/test.sbt @@ -1,5 +1,5 @@ lazy val root = (project in file(".")) .configs(IntegrationTest) .settings(Defaults.itSettings) - .settings(headerSettings(IntegrationTest): _*) + .settings(headerSettings(IntegrationTest)*) .settings(headerLicense := Some(HeaderLicense.ALv2("2015", "Heiko Seeberger"))) diff --git a/src/sbt-test/sbt-header/simple/project/test.sbt b/src/sbt-test/sbt-header/simple/project/test.sbt index 07e628c..856d7fa 100644 --- a/src/sbt-test/sbt-header/simple/project/test.sbt +++ b/src/sbt-test/sbt-header/simple/project/test.sbt @@ -3,4 +3,4 @@ val pluginVersion = .get("plugin.version") .getOrElse(sys.error("Sys prop plugin.version must be defined!")) -addSbtPlugin("de.heikoseeberger" % "sbt-header" % pluginVersion) +addSbtPlugin("com.github.sbt" % "sbt-header" % pluginVersion) diff --git a/src/sbt-test/sbt-header/simple/test.sbt b/src/sbt-test/sbt-header/simple/test.sbt index d15bcd6..4b33e5d 100644 --- a/src/sbt-test/sbt-header/simple/test.sbt +++ b/src/sbt-test/sbt-header/simple/test.sbt @@ -3,22 +3,30 @@ headerLicense := Some(HeaderLicense.ALv2("2015", "Heiko Seeberger")) // A file named exactly "routes" will NOT be taken into account even if the header extension is "routes" // A hidden file .routes must be treated with file name ".routes" and without extension // A hidden file .some.routes must be treated with extension "*.routes" -headerMappings := headerMappings.value + (HeaderFileType("routes") -> HeaderCommentStyle.cppStyleLineComment) +headerMappings := headerMappings.value + (HeaderFileType( + "routes" +) -> HeaderCommentStyle.cppStyleLineComment) // Do not exclude hidden files (.filename) unmanagedResources / excludeFilter := (_ => false) val checkFileContents = taskKey[Unit]("Verify file contents match expected contents") checkFileContents := { - checkFile("HasHeader.scala", scalaSource.in(Compile).value) - checkFile("HasNoHeader.scala", scalaSource.in(Compile).value) - checkFile("routes", resourceDirectory.in(Compile).value) - checkFile(".routes", resourceDirectory.in(Compile).value) // does not have extension, file name is only ".routes" - checkFile(".some.routes", resourceDirectory.in(Compile).value) // hidden file with extension .routes + checkFile("HasHeader.scala", (Compile / scalaSource).value) + checkFile("HasNoHeader.scala", (Compile / scalaSource).value) + checkFile("routes", (Compile / resourceDirectory).value) + checkFile( + ".routes", + (Compile / resourceDirectory).value + ) // does not have extension, file name is only ".routes" + checkFile( + ".some.routes", + (Compile / resourceDirectory).value + ) // hidden file with extension .routes def checkFile(name: String, sourceDir: sbt.File) = { val actualPath = (sourceDir / name).toString - val expectedPath = (resourceDirectory.in(Compile).value / s"${name}_expected").toString + val expectedPath = ((Compile / resourceDirectory).value / s"${name}_expected").toString val actual = scala.io.Source.fromFile(actualPath).mkString val expected = scala.io.Source.fromFile(expectedPath).mkString diff --git a/src/sbt-test/sbt-header/xml/project/test.sbt b/src/sbt-test/sbt-header/xml/project/test.sbt index 07e628c..856d7fa 100644 --- a/src/sbt-test/sbt-header/xml/project/test.sbt +++ b/src/sbt-test/sbt-header/xml/project/test.sbt @@ -3,4 +3,4 @@ val pluginVersion = .get("plugin.version") .getOrElse(sys.error("Sys prop plugin.version must be defined!")) -addSbtPlugin("de.heikoseeberger" % "sbt-header" % pluginVersion) +addSbtPlugin("com.github.sbt" % "sbt-header" % pluginVersion) diff --git a/src/sbt-test/sbt-header/xml/test.sbt b/src/sbt-test/sbt-header/xml/test.sbt index b5110ba..31b0c59 100644 --- a/src/sbt-test/sbt-header/xml/test.sbt +++ b/src/sbt-test/sbt-header/xml/test.sbt @@ -11,8 +11,8 @@ checkFileContents := { checkFile("order-no-header-no-xmldeclaration.xml") def checkFile(name: String) = { - val actualPath = (resourceDirectory.in(Compile).value / name).toString - val expectedPath = (resourceDirectory.in(Compile).value / s"${name}_expected").toString + val actualPath = ((Compile / resourceDirectory).value / name).toString + val expectedPath = ((Compile / resourceDirectory).value / s"${name}_expected").toString val actual = scala.io.Source.fromFile(actualPath).mkString val expected = scala.io.Source.fromFile(expectedPath).mkString diff --git a/src/test/scala/de/heikoseeberger/sbtheader/LicenseDetectionSpec.scala b/src/test/scala/de/heikoseeberger/sbtheader/LicenseDetectionSpec.scala deleted file mode 100644 index b8e7869..0000000 --- a/src/test/scala/de/heikoseeberger/sbtheader/LicenseDetectionSpec.scala +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright 2015 Heiko Seeberger - * - * 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. - */ - -package de.heikoseeberger.sbtheader - -import de.heikoseeberger.sbtheader.HeaderPlugin.autoImport.HeaderLicense._ -import sbt.URL -import org.scalatest.matchers.should.Matchers -import org.scalatest.wordspec.AnyWordSpec - -class LicenseDetectionSpec extends AnyWordSpec with Matchers { - - val organizationName = "Heiko Seeberger" - val yyyy = "2017" - val startYear = Some(yyyy) - val apache: (String, URL) = - ("Apache-2.0", new URL("https://spdx.org/licenses/Apache-2.0.html#licenseText")) - val mit: (String, URL) = ("MIT", new URL("https://spdx.org/licenses/MIT.html#licenseText")) - - val licenses: Map[License, (String, URL)] = Map( - BSD2Clause(yyyy.toString, organizationName) -> ("BSD-2-Clause", new URL( - "https://spdx.org/licenses/BSD-2-Clause.html#licenseText" - )), - BSD3Clause(yyyy.toString, organizationName) -> ("BSD-3-Clause", new URL( - "https://spdx.org/licenses/BSD-3-Clause.html#licenseText" - )), - AGPLv3OrLater(yyyy.toString, organizationName) -> ("AGPL-3.0-or-later", new URL( - "https://spdx.org/licenses/AGPL-3.0-or-later.html#licenseText" - )), - AGPLv3Only(yyyy.toString, organizationName) -> ("AGPL-3.0-only", new URL( - "https://spdx.org/licenses/AGPL-3.0-only.html#licenseText" - )), - AGPLv3(yyyy.toString, organizationName) -> ("AGPL-3.0", new URL( - "https://spdx.org/licenses/AGPL-3.0.html#licenseText" - )), - ALv2(yyyy.toString, organizationName) -> - apache, - GPLv3OrLater(yyyy.toString, organizationName) -> ("GPL-3.0-or-later", new URL( - "https://spdx.org/licenses/GPL-3.0-or-later.html#licenseText" - )), - GPLv3Only(yyyy.toString, organizationName) -> ("GPL-3.0-only", new URL( - "https://spdx.org/licenses/GPL-3.0-only.html#licenseText" - )), - GPLv3(yyyy.toString, organizationName) -> ("GPL-3.0", new URL( - "https://spdx.org/licenses/GPL-3.0.html#licenseText" - )), - LGPLv3OrLater(yyyy.toString, organizationName) -> ("LGPL-3.0-or-later", new URL( - "https://spdx.org/licenses/LGPL-3.0-or-later.html#licenseText" - )), - LGPLv3Only(yyyy.toString, organizationName) -> ("LGPL-3.0-only", new URL( - "https://spdx.org/licenses/LGPL-3.0-only.html#licenseText" - )), - LGPLv3(yyyy.toString, organizationName) -> ("LGPL-3.0", new URL( - "https://spdx.org/licenses/LGPL-3.0.html#licenseText" - )), - MIT(yyyy.toString, organizationName) -> mit, - MPLv2(yyyy.toString, organizationName) -> ("MPL-2.0", new URL( - "https://spdx.org/licenses/MPL-2.0.html#licenseText" - )) - ) - - "LicenseDetection" should { - "not detect a license when sbt licenses is empty" in { - LicenseDetection(List.empty, organizationName, startYear) shouldBe None - } - - "not detect a license when sbt licenses contains two licenses" in { - LicenseDetection( - List(apache, mit), - organizationName, - startYear - ) shouldBe None - } - - "not detect a license when startYear is None" in { - LicenseDetection( - List(apache), - organizationName, - None - ) shouldBe None - } - - "allow changing license style" in { - val expected = ALv2(yyyy, organizationName, LicenseStyle.SpdxSyntax) - - LicenseDetection( - List(apache), - organizationName, - startYear, - LicenseStyle.SpdxSyntax - ).map(_.text) shouldBe Some(expected.text) - } - - "use only the start year even when end year is set and equal" in { - val expected = ALv2(yyyy, organizationName, LicenseStyle.SpdxSyntax) - - LicenseDetection( - List(apache), - organizationName, - startYear.map(_.toInt), - startYear.map(_.toInt), - LicenseStyle.SpdxSyntax - ).map(_.text) shouldBe Some(expected.text) - } - - "detect end year when it is set and larger than start year" in { - val endYYYY = yyyy.toInt + 2 - val endYear = Some(endYYYY) - val expected = ALv2(s"$yyyy-$endYYYY", organizationName, LicenseStyle.SpdxSyntax) - - LicenseDetection( - List(apache), - organizationName, - startYear.map(_.toInt), - endYear, - LicenseStyle.SpdxSyntax - ).map(_.text) shouldBe Some(expected.text) - } - - licenses.foreach { case (license, sbtLicense) => - s"detect ${license.getClass.getSimpleName} license" in { - LicenseDetection(List(sbtLicense), organizationName, startYear) - .map(_.text) shouldBe Some( - license.text - ) - } - } - } -} diff --git a/src/test/scala/de/heikoseeberger/sbtheader/CommentStyleSpec.scala b/src/test/scala/sbtheader/CommentStyleSpec.scala similarity index 95% rename from src/test/scala/de/heikoseeberger/sbtheader/CommentStyleSpec.scala rename to src/test/scala/sbtheader/CommentStyleSpec.scala index 618e7d2..981d914 100644 --- a/src/test/scala/de/heikoseeberger/sbtheader/CommentStyleSpec.scala +++ b/src/test/scala/sbtheader/CommentStyleSpec.scala @@ -1,22 +1,13 @@ /* - * Copyright 2015 Heiko Seeberger + * Copyright (c) 2015 - 2025, Heiko Seeberger + * Copyright (c) 2025, sbt plugin contributors * - * 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. + * SPDX-License-Identifier: Apache-2.0 */ -package de.heikoseeberger.sbtheader +package sbtheader -import de.heikoseeberger.sbtheader.CommentStyle._ +import sbtheader.CommentStyle.* import org.scalatest.matchers.should.Matchers import org.scalatest.wordspec.AnyWordSpec diff --git a/src/test/scala/de/heikoseeberger/sbtheader/HeaderCreatorSpec.scala b/src/test/scala/sbtheader/HeaderCreatorSpec.scala similarity index 91% rename from src/test/scala/de/heikoseeberger/sbtheader/HeaderCreatorSpec.scala rename to src/test/scala/sbtheader/HeaderCreatorSpec.scala index e628c5c..375dbd0 100644 --- a/src/test/scala/de/heikoseeberger/sbtheader/HeaderCreatorSpec.scala +++ b/src/test/scala/sbtheader/HeaderCreatorSpec.scala @@ -1,26 +1,17 @@ /* - * Copyright 2015 Heiko Seeberger + * Copyright (c) 2015 - 2025, Heiko Seeberger + * Copyright (c) 2025, sbt plugin contributors * - * 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. + * SPDX-License-Identifier: Apache-2.0 */ -package de.heikoseeberger.sbtheader +package sbtheader import java.io.ByteArrayInputStream import sbt.Logger -import de.heikoseeberger.sbtheader.HeaderPlugin.autoImport.HeaderCommentStyle.hashLineComment -import de.heikoseeberger.sbtheader.HeaderPlugin.autoImport.HeaderLicense.Custom +import sbtheader.HeaderPlugin.autoImport.HeaderCommentStyle.hashLineComment +import sbtheader.HeaderPlugin.autoImport.HeaderLicense.Custom import scala.util.matching.Regex import org.scalatest.matchers.should.Matchers @@ -125,7 +116,7 @@ final class HeaderCreatorSpec extends AnyWordSpec with Matchers { "given a file with shebang" should { val shebang = "#!/bin/bash" + NewLine - val script = + val script = """|echo Hello World |exit 0 |""".stripMargin @@ -148,7 +139,7 @@ final class HeaderCreatorSpec extends AnyWordSpec with Matchers { "given an XML file with XML declaration" should { val xmlDeclaration = """""" + NewLine - val xmlBody = + val xmlBody = """| | | my.group @@ -186,7 +177,7 @@ final class HeaderCreatorSpec extends AnyWordSpec with Matchers { "given a file with an existing copyright year" should { val yearPreservingStyle = CommentStyle.cStyleBlockComment.copy(commentCreator = new CommentCreator() { - val Pattern: Regex = "(?s).*?(\\d{4}(-\\d{4})?).*".r + val Pattern: Regex = "(?s).*?(\\d{4}(-\\d{4})?).*".r def findYear(header: String): Option[String] = header match { case Pattern(years, _) => Some(years) diff --git a/src/test/scala/sbtheader/LicenseDetectionSpec.scala b/src/test/scala/sbtheader/LicenseDetectionSpec.scala new file mode 100644 index 0000000..ef5f5f4 --- /dev/null +++ b/src/test/scala/sbtheader/LicenseDetectionSpec.scala @@ -0,0 +1,178 @@ +/* + * Copyright (c) 2015 - 2025, Heiko Seeberger + * Copyright (c) 2025, sbt plugin contributors + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package sbtheader + +import sbtheader.HeaderPlugin.autoImport.HeaderLicense +import HeaderLicense.* +import sbt.url +import org.scalatest.matchers.should.Matchers +import org.scalatest.wordspec.AnyWordSpec +import PluginCompat.{ *, given } + +class LicenseDetectionSpec extends AnyWordSpec with Matchers { + + val organizationName = "Heiko Seeberger" + val yyyy = "2017" + val startYear = Some(yyyy) + val apache = sbt.License.Apache2 + val mit = sbt.License.MIT + + val licenses: Map[sbtheader.License, LicenseRef] = Map( + BSD2Clause(yyyy.toString, organizationName) -> mkLicense( + "BSD-2-Clause", + url( + "https://spdx.org/licenses/BSD-2-Clause.html#licenseText" + ) + ), + BSD3Clause(yyyy.toString, organizationName) -> mkLicense( + "BSD-3-Clause", + url( + "https://spdx.org/licenses/BSD-3-Clause.html#licenseText" + ) + ), + AGPLv3OrLater(yyyy.toString, organizationName) -> mkLicense( + "AGPL-3.0-or-later", + url( + "https://spdx.org/licenses/AGPL-3.0-or-later.html#licenseText" + ) + ), + AGPLv3Only(yyyy.toString, organizationName) -> mkLicense( + "AGPL-3.0-only", + url( + "https://spdx.org/licenses/AGPL-3.0-only.html#licenseText" + ) + ), + AGPLv3(yyyy.toString, organizationName) -> mkLicense( + "AGPL-3.0", + url( + "https://spdx.org/licenses/AGPL-3.0.html#licenseText" + ) + ), + ALv2(yyyy.toString, organizationName) -> + apache, + GPLv3OrLater(yyyy.toString, organizationName) -> mkLicense( + "GPL-3.0-or-later", + url( + "https://spdx.org/licenses/GPL-3.0-or-later.html#licenseText" + ) + ), + GPLv3Only(yyyy.toString, organizationName) -> mkLicense( + "GPL-3.0-only", + url( + "https://spdx.org/licenses/GPL-3.0-only.html#licenseText" + ) + ), + GPLv3(yyyy.toString, organizationName) -> mkLicense( + "GPL-3.0", + url( + "https://spdx.org/licenses/GPL-3.0.html#licenseText" + ) + ), + LGPLv3OrLater(yyyy.toString, organizationName) -> mkLicense( + "LGPL-3.0-or-later", + url( + "https://spdx.org/licenses/LGPL-3.0-or-later.html#licenseText" + ) + ), + LGPLv3Only(yyyy.toString, organizationName) -> mkLicense( + "LGPL-3.0-only", + url( + "https://spdx.org/licenses/LGPL-3.0-only.html#licenseText" + ) + ), + LGPLv3(yyyy.toString, organizationName) -> mkLicense( + "LGPL-3.0", + url( + "https://spdx.org/licenses/LGPL-3.0.html#licenseText" + ) + ), + HeaderLicense.MIT(yyyy.toString, organizationName) -> mit, + MPLv2(yyyy.toString, organizationName) -> mkLicense( + "MPL-2.0", + url( + "https://spdx.org/licenses/MPL-2.0.html#licenseText" + ) + ) + ) + + "LicenseDetection" should { + "not detect a license when sbt licenses is empty" in + assert(LicenseDetection(List.empty, organizationName, startYear) == None) + + "not detect a license when sbt licenses contains two licenses" in + assert( + LicenseDetection( + List(apache, mit), + organizationName, + startYear + ) == None + ) + + "not detect a license when startYear is None" in + assert( + LicenseDetection( + List(apache), + organizationName, + None + ) == None + ) + + "allow changing license style" in { + val expected = ALv2(yyyy, organizationName, LicenseStyle.SpdxSyntax) + + assert( + LicenseDetection( + List(apache), + organizationName, + startYear, + LicenseStyle.SpdxSyntax + ).map(_.text) == Some(expected.text) + ) + } + + "use only the start year even when end year is set and equal" in { + val expected = ALv2(yyyy, organizationName, LicenseStyle.SpdxSyntax) + + assert( + LicenseDetection( + List(apache), + organizationName, + startYear.map(_.toInt), + startYear.map(_.toInt), + LicenseStyle.SpdxSyntax + ).map(_.text) == Some(expected.text) + ) + } + + "detect end year when it is set and larger than start year" in { + val endYYYY = yyyy.toInt + 2 + val endYear = Some(endYYYY) + val expected = ALv2(s"$yyyy-$endYYYY", organizationName, LicenseStyle.SpdxSyntax) + + assert( + LicenseDetection( + List(apache), + organizationName, + startYear.map(_.toInt), + endYear, + LicenseStyle.SpdxSyntax + ).map(_.text) == Some(expected.text) + ) + } + + licenses.foreach { case (license, sbtLicense) => + s"detect ${license.getClass.getSimpleName} license" in + assert( + LicenseDetection(List(sbtLicense), organizationName, startYear) + .map(_.text) == Some( + license.text + ) + ) + } + } +} diff --git a/src/test/scala/de/heikoseeberger/sbtheader/LicenseSpec.scala b/src/test/scala/sbtheader/LicenseSpec.scala similarity index 91% rename from src/test/scala/de/heikoseeberger/sbtheader/LicenseSpec.scala rename to src/test/scala/sbtheader/LicenseSpec.scala index 1524efa..c861e2e 100644 --- a/src/test/scala/de/heikoseeberger/sbtheader/LicenseSpec.scala +++ b/src/test/scala/sbtheader/LicenseSpec.scala @@ -1,22 +1,13 @@ /* - * Copyright 2015 Heiko Seeberger + * Copyright (c) 2015 - 2025, Heiko Seeberger + * Copyright (c) 2025, sbt plugin contributors * - * 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. + * SPDX-License-Identifier: Apache-2.0 */ -package de.heikoseeberger.sbtheader +package sbtheader -import de.heikoseeberger.sbtheader.HeaderPlugin.autoImport.HeaderLicense._ +import sbtheader.HeaderPlugin.autoImport.HeaderLicense.* import org.scalatest.matchers.should.Matchers import org.scalatest.wordspec.AnyWordSpec @@ -25,7 +16,7 @@ class licenseSpec extends AnyWordSpec with Matchers { "AGPLv3OrLater" should { "contain the AGPLv3 or later license with the given copyright year and owner" in { - val agplv3 = AGPLv3OrLater("2020", "Edward Samson").text + val agplv3 = AGPLv3OrLater("2020", "Edward Samson").text val expected = s"""|Copyright (C) 2020 Edward Samson | @@ -50,7 +41,7 @@ class licenseSpec extends AnyWordSpec with Matchers { "AGPLv3Only" should { "contain the AGPLv3 only license with the given copyright year and owner" in { - val agplv3 = AGPLv3Only("2020", "Edward Samson").text + val agplv3 = AGPLv3Only("2020", "Edward Samson").text val expected = s"""|Copyright (C) 2020 Edward Samson | @@ -74,7 +65,7 @@ class licenseSpec extends AnyWordSpec with Matchers { "AGPLv3" should { "contain the AGPLv3 license with the given copyright year and owner" in { - val agplv3 = AGPLv3("2015", "Heiko Seeberger").text + val agplv3 = AGPLv3("2015", "Heiko Seeberger").text val expected = s"""|Copyright (C) 2015 Heiko Seeberger | @@ -99,7 +90,7 @@ class licenseSpec extends AnyWordSpec with Matchers { "Apache 2.0" should { "contain the Apache 2.0 license with the given copyright year and owner" in { - val alv2 = ALv2("2015", "Heiko Seeberger").text + val alv2 = ALv2("2015", "Heiko Seeberger").text val expected = s"""|Copyright 2015 Heiko Seeberger | @@ -123,7 +114,7 @@ class licenseSpec extends AnyWordSpec with Matchers { "BSD 2 Clause" should { "contain the BSD 2 Clause license with the given copyright year and owner" in { - val bsd2 = BSD2Clause("2015", "Heiko Seeberger").text + val bsd2 = BSD2Clause("2015", "Heiko Seeberger").text val expected = s"""|Copyright (c) 2015, Heiko Seeberger |All rights reserved. @@ -157,7 +148,7 @@ class licenseSpec extends AnyWordSpec with Matchers { "BSD 3 Clause" should { "contain the BSD 3 Clause license with the given copyright year and owner" in { - val bsd3 = BSD3Clause("2015", "Heiko Seeberger").text + val bsd3 = BSD3Clause("2015", "Heiko Seeberger").text val expected = s"""|Copyright (c) 2015, Heiko Seeberger |All rights reserved. @@ -195,7 +186,7 @@ class licenseSpec extends AnyWordSpec with Matchers { "GPLv3OrLater" should { "contain the GPLv3 or later license with the given copyright year and owner" in { - val gplv3 = GPLv3OrLater("2020", "Edward Samson").text + val gplv3 = GPLv3OrLater("2020", "Edward Samson").text val expected = s"""|Copyright (C) 2020 Edward Samson | @@ -220,7 +211,7 @@ class licenseSpec extends AnyWordSpec with Matchers { "GPLv3Only" should { "contain the GPLv3 only license with the given copyright year and owner" in { - val gplv3 = GPLv3Only("2020", "Edward Samson").text + val gplv3 = GPLv3Only("2020", "Edward Samson").text val expected = s"""|Copyright (C) 2020 Edward Samson | @@ -244,7 +235,7 @@ class licenseSpec extends AnyWordSpec with Matchers { "GPLv3" should { "contain the GPLv3 license with the given copyright year and owner" in { - val gplv3 = GPLv3("2015", "Heiko Seeberger").text + val gplv3 = GPLv3("2015", "Heiko Seeberger").text val expected = s"""|Copyright (C) 2015 Heiko Seeberger | @@ -269,7 +260,7 @@ class licenseSpec extends AnyWordSpec with Matchers { "LGPLv3OrLater" should { "contain the LGPLv3 or later license with the given copyright year and owner" in { - val lgplv3 = LGPLv3OrLater("2020", "Edward Samson").text + val lgplv3 = LGPLv3OrLater("2020", "Edward Samson").text val expected = s"""|Copyright (C) 2020 Edward Samson | @@ -294,7 +285,7 @@ class licenseSpec extends AnyWordSpec with Matchers { "LGPLv3Only" should { "contain the LGPLv3 only license with the given copyright year and owner" in { - val lgplv3 = LGPLv3Only("2020", "Edward Samson").text + val lgplv3 = LGPLv3Only("2020", "Edward Samson").text val expected = s"""|Copyright (C) 2020 Edward Samson | @@ -318,7 +309,7 @@ class licenseSpec extends AnyWordSpec with Matchers { "LGPLv3" should { "contain the LGPLv3 license with the given copyright year and owner" in { - val lgplv3 = LGPLv3("2015", "Heiko Seeberger").text + val lgplv3 = LGPLv3("2015", "Heiko Seeberger").text val expected = s"""|Copyright (C) 2015 Heiko Seeberger | @@ -343,7 +334,7 @@ class licenseSpec extends AnyWordSpec with Matchers { "MIT" should { "contain the MIT license with the given copyright year and owner" in { - val mit = MIT("2015", "Heiko Seeberger").text + val mit = MIT("2015", "Heiko Seeberger").text val expected = s"""|Copyright (c) 2015 Heiko Seeberger | @@ -372,7 +363,7 @@ class licenseSpec extends AnyWordSpec with Matchers { "MPL 2.0" should { "contain the MPL 2.0 license with the given copyright year and owner" in { - val mit = MPLv2("2015", "Heiko Seeberger").text + val mit = MPLv2("2015", "Heiko Seeberger").text val expected = s"""|Copyright (c) 2015 Heiko Seeberger | @@ -388,7 +379,7 @@ class licenseSpec extends AnyWordSpec with Matchers { "MPL 2.0 license without copyright" should { "contain the MPL 2.0 license without copyright" in { - val mit = MPLv2_NoCopyright.text + val mit = MPLv2_NoCopyright.text val expected = s"""|This Source Code Form is subject to the terms of the Mozilla Public |License, v. 2.0. If a copy of the MPL was not distributed with this