This is an automated email from the ASF dual-hosted git repository.

mdedetrich pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-pekko-projection.git

commit 012d4ff3148b290d61066ddc671f5c75f1c2c670
Author: Matthew de Detrich <[email protected]>
AuthorDate: Mon Apr 3 18:01:30 2023 +0200

    Update CopyrightHeader to deal with Apache license headers
---
 .github/workflows/headers.yml |  30 ++++++++++
 project/CopyrightHeader.scala | 128 ++++++++++++++++++++++++++++++------------
 2 files changed, 122 insertions(+), 36 deletions(-)

diff --git a/.github/workflows/headers.yml b/.github/workflows/headers.yml
new file mode 100644
index 0000000..5faf67d
--- /dev/null
+++ b/.github/workflows/headers.yml
@@ -0,0 +1,30 @@
+name: Headers
+
+on:
+  pull_request:
+
+permissions: {}
+
+jobs:
+  check-headers:
+    name: Check headers
+    runs-on: ubuntu-20.04
+    steps:
+      - name: Checkout
+        uses: actions/checkout@v3
+
+      - name: Setup Java 8
+        uses: actions/setup-java@v3
+        with:
+          distribution: temurin
+          java-version: 11
+
+      - name: Cache Coursier cache
+        uses: coursier/[email protected]
+
+      - name: Check headers
+        run: |-
+          sbt \
+          -Dsbt.override.build.repos=false \
+          -Dsbt.log.noformat=false \
+          +headerCheckAll
diff --git a/project/CopyrightHeader.scala b/project/CopyrightHeader.scala
index 78595a4..99c96a1 100644
--- a/project/CopyrightHeader.scala
+++ b/project/CopyrightHeader.scala
@@ -1,53 +1,109 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * license agreements; and to You under the Apache License, version 2.0:
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * This file is part of the Apache Pekko project, derived from Akka.
+ */
+
 /*
  * Copyright (C) 2020-2021 Lightbend Inc. <https://www.lightbend.com>
  */
-import de.heikoseeberger.sbtheader.CommentCreator
-import de.heikoseeberger.sbtheader.HeaderPlugin
+
+import de.heikoseeberger.sbtheader.HeaderPlugin.autoImport._
+import de.heikoseeberger.sbtheader.{ CommentCreator, HeaderPlugin, NewLine }
+import org.apache.commons.lang3.StringUtils
+import sbt.Keys._
 import sbt._
 
-object CopyrightHeader extends AutoPlugin {
-  import HeaderPlugin.autoImport._
+trait CopyrightHeader extends AutoPlugin {
+
+  override def requires: Plugins = HeaderPlugin
 
-  override def requires = HeaderPlugin
-  override def trigger = allRequirements
+  override def trigger: PluginTrigger = allRequirements
 
-  override def projectSettings =
-    Def.settings(Seq(Compile, Test).flatMap { config =>
+  protected def headerMappingSettings: Seq[Def.Setting[_]] =
+    Seq(Compile, Test, IntegrationTest).flatMap { config =>
       inConfig(config)(
         Seq(
-          headerLicense := Some(HeaderLicense.Custom(headerFor(CurrentYear))),
+          headerLicense := Some(HeaderLicense.Custom(apacheHeader)),
           headerMappings := headerMappings.value ++ Map(
             HeaderFileType.scala -> cStyleComment,
-            HeaderFileType.java -> cStyleComment)))
-    })
-
-  // We hard-code this so PR's created in year X will not suddenly fail in X+1.
-  // Of course we should remember to update it early in the year.
-  val CurrentYear = "2022"
-  val CopyrightPattern = "Copyright \\([Cc]\\) (\\d{4}(-\\d{4})?) 
(Lightbend|Typesafe) Inc. <.*>".r
-  val CopyrightHeaderPattern = s"(?s).*${CopyrightPattern}.*".r
-
-  def headerFor(year: String): String =
-    s"Copyright (C) $year Lightbend Inc. <https://www.lightbend.com>"
-
-  private def lightbendCommentCreator(commentCreator: CommentCreator) = new 
CommentCreator() {
-
-    def updateLightbendHeader(header: String): String = header match {
-      case CopyrightHeaderPattern(years, null, _) =>
-        if (years != CurrentYear)
-          CopyrightPattern.replaceFirstIn(header, headerFor(years + "-" + 
CurrentYear))
-        else
-          CopyrightPattern.replaceFirstIn(header, headerFor(years))
-      case CopyrightHeaderPattern(years, endYears, _) =>
-        CopyrightPattern.replaceFirstIn(header, 
headerFor(years.replace(endYears, "-" + CurrentYear)))
-      case _ =>
-        header
+            HeaderFileType.java -> cStyleComment,
+            HeaderFileType.conf -> hashLineComment,
+            HeaderFileType("template") -> cStyleComment)))
+    }
+
+  override def projectSettings: Seq[Def.Setting[_]] =
+    Def.settings(headerMappingSettings, additional) ++ Defaults.itSettings ++
+    headerSettings(IntegrationTest)
+
+  def additional: Seq[Def.Setting[_]] =
+    Def.settings(Compile / compile := {
+        (Compile / headerCreate).value
+        (Compile / compile).value
+      },
+      Test / compile := {
+        (Test / headerCreate).value
+        (Test / compile).value
+      })
+
+  def apacheHeader: String =
+    """Licensed to the Apache Software Foundation (ASF) under one or more
+      |license agreements; and to You under the Apache License, version 2.0:
+      |
+      |  https://www.apache.org/licenses/LICENSE-2.0
+      |
+      |This file is part of the Apache Pekko project, derived from Akka.
+      |""".stripMargin
+
+  val apacheSpdxHeader: String = "SPDX-License-Identifier: Apache-2.0"
+
+  val cStyleComment = 
HeaderCommentStyle.cStyleBlockComment.copy(commentCreator = new 
CommentCreator() {
+
+    override def apply(text: String, existingText: Option[String]): String = {
+      val formatted = existingText match {
+        case Some(currentText) if isValidCopyrightAnnotated(currentText) =>
+          currentText
+        case Some(currentText) if isLightbendCopyrighted(currentText) =>
+          HeaderCommentStyle.cStyleBlockComment.commentCreator(text, 
existingText) + NewLine * 2 + currentText
+        case Some(currentText) =>
+          throw new IllegalStateException(s"Unable to detect copyright for 
header:[${currentText}]")
+        case None =>
+          HeaderCommentStyle.cStyleBlockComment.commentCreator(text, 
existingText)
+      }
+      formatted.trim
     }
+  })
+
+  val hashLineComment = HeaderCommentStyle.hashLineComment.copy(commentCreator 
= new CommentCreator() {
 
+    // deliberately hardcode use of apacheSpdxHeader and ignore input text
     override def apply(text: String, existingText: Option[String]): String = {
-      existingText.map(updateLightbendHeader).getOrElse(commentCreator(text, 
existingText)).trim
+      val formatted = existingText match {
+        case Some(currentText) if isApacheCopyrighted(currentText) =>
+          currentText
+        case Some(currentText) =>
+          HeaderCommentStyle.hashLineComment.commentCreator(apacheSpdxHeader, 
existingText) + NewLine * 2 + currentText
+        case None =>
+          HeaderCommentStyle.hashLineComment.commentCreator(apacheSpdxHeader, 
existingText)
+      }
+      formatted.trim
     }
+  })
+
+  private def isApacheCopyrighted(text: String): Boolean =
+    StringUtils.containsIgnoreCase(text, "licensed to the apache software 
foundation (asf)") ||
+    StringUtils.containsIgnoreCase(text, 
"www.apache.org/licenses/license-2.0") ||
+    StringUtils.contains(text, "Apache-2.0")
+
+  private def isLightbendCopyrighted(text: String): Boolean =
+    StringUtils.containsIgnoreCase(text, "lightbend inc.")
+
+  private def isValidCopyrightAnnotated(text: String): Boolean = {
+    isApacheCopyrighted(text)
   }
-  val cStyleComment = HeaderCommentStyle.cStyleBlockComment
-    .copy(commentCreator = 
lightbendCommentCreator(HeaderCommentStyle.cStyleBlockComment.commentCreator))
 }
+
+object CopyrightHeader extends CopyrightHeader


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to