| /* |
| * 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, which was derived from Akka. |
| */ |
| |
| package org.apache.pekko.grpc |
| |
| import java.nio.file.{ Files, Path, Paths } |
| |
| import scala.collection.JavaConverters._ |
| import scala.sys.process._ |
| import scala.util.matching.UnanchoredRegex |
| |
| import org.eclipse.jgit.diff.RawText |
| import sbt._ |
| import sbt.Keys._ |
| |
| object VersionSyncCheckPlugin extends AutoPlugin { |
| override def trigger = allRequirements |
| |
| object autoImport { |
| val grpcVersionSyncCheck = taskKey[Unit]("") |
| val googleProtobufVersionSyncCheck = taskKey[Unit]("") |
| } |
| import autoImport._ |
| |
| override def globalSettings = Seq( |
| grpcVersionSyncCheck := versionSyncCheckImpl( |
| "gRPC", |
| Dependencies.Versions.grpc, |
| raw"""(?i)grpc.?(?i)version.{1,9}(\d+\.\d+\.\d+)""".r.unanchored, |
| Seq( |
| Paths.get("plugin-tester-java/pom.xml"), |
| Paths.get("plugin-tester-scala/pom.xml"), |
| Paths.get("sbt-plugin/src/sbt-test/gen-scala-server/00-interop/build.sbt"), |
| Paths.get("gradle-plugin/src/main/groovy/org/apache/pekko/grpc/gradle/PekkoGrpcPluginExtension.groovy"))).value, |
| googleProtobufVersionSyncCheck := versionSyncCheckImpl( |
| "Google Protobuf", |
| Dependencies.Versions.googleProtoc, |
| raw"""(?i)protoc_?version.*= ?"-?v?(\d+\.\d+\.\d+)"""".r.unanchored, |
| Seq( |
| Paths.get("maven-plugin/src/main/maven/plugin.xml"), |
| Paths.get("gradle-plugin/src/main/groovy/org/apache/pekko/grpc/gradle/PekkoGrpcPluginExtension.groovy"))).value) |
| |
| def versionSyncCheckImpl( |
| name: String, |
| expectedVersion: String, |
| VersionRegex: UnanchoredRegex, |
| knownFiles: Seq[Path]) = |
| Def.task[Unit] { |
| val log = state.value.log |
| log.info(s"Running $name version sync check, expecting version $expectedVersion") |
| |
| def versions(path: Path): (Path, Seq[String]) = |
| ( |
| path, |
| Files |
| .lines(path) |
| .iterator |
| .asScala |
| .collect { |
| case VersionRegex(version) => version |
| } |
| .toSeq) |
| |
| log.info("Sanity checking regex extraction against known files") |
| val mismatchVersions = knownFiles.map(versions).filterNot(_._2.toSet == Set(expectedVersion)).toVector |
| if (mismatchVersions.isEmpty) { |
| log.info("Sanity check passed") |
| } else { |
| mismatchVersions.foreach { |
| case (path, versions) => |
| log.error(s"Found sanity check $name version mismatch: $path -> $versions") |
| } |
| fail("Sanity check failed") |
| } |
| |
| val buildBase = (ThisBuild / baseDirectory).value |
| val process = Process("git ls-tree -z --full-tree -r --name-only HEAD", buildBase) |
| val paths = (process !! log).trim |
| .split('\u0000') |
| .iterator |
| .map(path => Paths.get(path)) |
| .filter(Files.exists(_)) |
| .filterNot(path => RawText.isBinary(Files.newInputStream(path))) |
| .filterNot(path => path.toString.endsWith(".enc")) // encrypted blob |
| |
| var mismatch = false |
| |
| for ((path, versions) <- paths.map(versions(_)).filter(_._2.nonEmpty)) { |
| if (versions.forall(_ == expectedVersion)) { |
| log.info(s"Found matching $name version $expectedVersion in $path") |
| } else { |
| log.error(s"Found $name version mismatch: $path -> $versions") |
| mismatch = true |
| } |
| } |
| |
| if (mismatch) { |
| fail(s"$name version sync check failed, expected $expectedVersion") |
| } |
| |
| log.info(s"$name version sync check success") |
| } |
| |
| private def fail(message: String): Nothing = { |
| val fail = new MessageOnlyException(message) |
| fail.setStackTrace(new Array[StackTraceElement](0)) |
| throw fail |
| } |
| } |