使用 sbt.version 1.2.8 发布到 nexus 的 Sbt 插件无法由使用 sbt.version >1.2.8 的 sbt 项目解决

Posted

技术标签:

【中文标题】使用 sbt.version 1.2.8 发布到 nexus 的 Sbt 插件无法由使用 sbt.version >1.2.8 的 sbt 项目解决【英文标题】:Sbt plugin published to nexus with sbt.version 1.2.8 is not resolved by sbt projects which are using sbt.version >1.2.8 【发布时间】:2021-04-09 23:00:39 【问题描述】:

我们使用 sbt clean compile publishM2 将 sbt 插件发布到本地 m2 存储库。

下面是简化的插件源代码:-

build.sbt :-

name := "base-plugin"
version := "0.1"
organization := "io.github.moglideveloper"

sbtPlugin := true

val pluginDeveloper = Developer("mogli", "mogli", "moglideveloper@gmail.com", url("https://github.com/moglideveloper"))
developers := List(pluginDeveloper)

homepage := Some(url("https://github.com/moglideveloper/BasePlugin"))
scmInfo := Some(ScmInfo(url("https://github.com/moglideveloper/BasePlugin"), "git@github.com:moglideveloper/BasePlugin.git"))

licenses += ("MIT", url("https://opensource.org/licenses/MIT"))

publishMavenStyle := true
publishArtifact in Test := false
publishConfiguration := publishConfiguration.value.withOverwrite(true)
publishTo := Some(Opts.resolver.sonatypeStaging)

build.properties:-

sbt.version=1.2.8

由于存在 sbt 升级问题,我们正在使用 1.2.8:-

https://github.com/xerial/sbt-sonatype/pull/98

https://github.com/sbt/sbt/issues/5049

BasePlugin.scala :-

package io.moglideveloper.base_plugin

import sbt._

object BasePlugin extends AutoPlugin 

  lazy val hello = taskKey[Unit]("just say hello")

  override def trigger = allRequirements

  override lazy val projectSettings = Seq(
    hello := 
      println("hello")
    
  )


现在,任何 sbt 版本 1.x 都无法正确解析上述发布的插件,例如 sbt.version=1.2.8

下面是异常跟踪:-

/Users/mogli/.sdkman/candidates/java/11.0.9.hs-adpt/bin/java -Djline.terminal=jline.UnsupportedTerminal -Dsbt.log.noformat=true -Dfile.encoding=UTF-8 -Didea.managed=true -Dfile.encoding=UTF-8 -jar /Users/mogli/Library/Application Support/JetBrains/IdeaIC2020.3/plugins/Scala/launcher/sbt-launch.jar
[info] Loading settings for project resolvecheck-build from plugins.sbt ...
[info] Loading project definition from /Users/mogli/sources/ResolveCheck/project
[info] Updating ProjectRef(uri("file:/Users/mogli/sources/ResolveCheck/project/"), "resolvecheck-build")...
[warn]  module not found: io.github.moglideveloper#base-plugin;0.1
[warn] ==== typesafe-ivy-releases: tried
[warn]   https://repo.typesafe.com/typesafe/ivy-releases/io.github.moglideveloper/base-plugin/scala_2.12/sbt_1.0/0.1/ivys/ivy.xml
[warn] ==== sbt-plugin-releases: tried
[warn]   https://repo.scala-sbt.org/scalasbt/sbt-plugin-releases/io.github.moglideveloper/base-plugin/scala_2.12/sbt_1.0/0.1/ivys/ivy.xml
[warn] ==== local: tried
[warn]   /Users/mogli/.ivy2/local/io.github.moglideveloper/base-plugin/scala_2.12/sbt_1.0/0.1/ivys/ivy.xml
[warn] ==== public: tried
[warn]   https://repo1.maven.org/maven2/io/github/moglideveloper/base-plugin_2.12_1.0/0.1/base-plugin-0.1.pom
[warn] ==== local-preloaded-ivy: tried
[warn]   /Users/mogli/.sbt/preloaded/io.github.moglideveloper/base-plugin/0.1/ivys/ivy.xml
[warn] ==== local-preloaded: tried
[warn]   file:////Users/mogli/.sbt/preloaded/io/github/moglideveloper/base-plugin_2.12_1.0/0.1/base-plugin-0.1.pom
[warn] ==== Local Repository: tried
[warn]  ::::::::::::::::::::::::::::::::::::::::::::::
[warn]  ::          UNRESOLVED DEPENDENCIES         ::
[warn]  ::::::::::::::::::::::::::::::::::::::::::::::
[warn]  :: io.github.moglideveloper#base-plugin;0.1: not found
[warn]  ::::::::::::::::::::::::::::::::::::::::::::::
[warn]
[warn]  Note: Some unresolved dependencies have extra attributes.  Check that these dependencies exist with the requested attributes.
[warn]      io.github.moglideveloper:base-plugin:0.1 (scalaVersion=2.12, sbtVersion=1.0)
[warn]
[warn]  Note: Unresolved dependencies path:
[warn]      io.github.moglideveloper:base-plugin:0.1 (scalaVersion=2.12, sbtVersion=1.0) (/Users/mogli/sources/ResolveCheck/project/plugins.sbt#L2-3)
[warn]        +- default:resolvecheck-build:0.1.0-SNAPSHOT (scalaVersion=2.12, sbtVersion=1.0)
[error] sbt.librarymanagement.ResolveException: unresolved dependency: io.github.moglideveloper#base-plugin;0.1: not found
[error]     at sbt.internal.librarymanagement.IvyActions$.resolveAndRetrieve(IvyActions.scala:332)
[error]     at sbt.internal.librarymanagement.IvyActions$.$anonfun$updateEither$1(IvyActions.scala:208)
[error]     at sbt.internal.librarymanagement.IvySbt$Module.$anonfun$withModule$1(Ivy.scala:239)
[error]     at sbt.internal.librarymanagement.IvySbt.$anonfun$withIvy$1(Ivy.scala:204)
[error]     at sbt.internal.librarymanagement.IvySbt.sbt$internal$librarymanagement$IvySbt$$action$1(Ivy.scala:70)
[error]     at sbt.internal.librarymanagement.IvySbt$$anon$3.call(Ivy.scala:77)
[error]     at xsbt.boot.Locks$GlobalLock.withChannel$1(Locks.scala:95)
[error]     at xsbt.boot.Locks$GlobalLock.xsbt$boot$Locks$GlobalLock$$withChannelRetries$1(Locks.scala:80)
[error]     at xsbt.boot.Locks$GlobalLock$$anonfun$withFileLock$1.apply(Locks.scala:99)
[error]     at xsbt.boot.Using$.withResource(Using.scala:10)
[error]     at xsbt.boot.Using$.apply(Using.scala:9)
[error]     at xsbt.boot.Locks$GlobalLock.ignoringDeadlockAvoided(Locks.scala:60)
[error]     at xsbt.boot.Locks$GlobalLock.withLock(Locks.scala:50)
[error]     at xsbt.boot.Locks$.apply0(Locks.scala:31)
[error]     at xsbt.boot.Locks$.apply(Locks.scala:28)
[error]     at sbt.internal.librarymanagement.IvySbt.withDefaultLogger(Ivy.scala:77)
[error]     at sbt.internal.librarymanagement.IvySbt.withIvy(Ivy.scala:199)
[error]     at sbt.internal.librarymanagement.IvySbt.withIvy(Ivy.scala:196)
[error]     at sbt.internal.librarymanagement.IvySbt$Module.withModule(Ivy.scala:238)
[error]     at sbt.internal.librarymanagement.IvyActions$.updateEither(IvyActions.scala:193)
[error]     at sbt.librarymanagement.ivy.IvyDependencyResolution.update(IvyDependencyResolution.scala:20)
[error]     at sbt.librarymanagement.DependencyResolution.update(DependencyResolution.scala:56)
[error]     at sbt.internal.LibraryManagement$.resolve$1(LibraryManagement.scala:45)
[error]     at sbt.internal.LibraryManagement$.$anonfun$cachedUpdate$12(LibraryManagement.scala:93)
[error]     at sbt.util.Tracked$.$anonfun$lastOutput$1(Tracked.scala:68)
[error]     at sbt.internal.LibraryManagement$.$anonfun$cachedUpdate$19(LibraryManagement.scala:106)
[error]     at scala.util.control.Exception$Catch.apply(Exception.scala:224)
[error]     at sbt.internal.LibraryManagement$.$anonfun$cachedUpdate$11(LibraryManagement.scala:106)
[error]     at sbt.internal.LibraryManagement$.$anonfun$cachedUpdate$11$adapted(LibraryManagement.scala:89)
[error]     at sbt.util.Tracked$.$anonfun$inputChanged$1(Tracked.scala:149)
[error]     at sbt.internal.LibraryManagement$.cachedUpdate(LibraryManagement.scala:120)
[error]     at sbt.Classpaths$.$anonfun$updateTask$5(Defaults.scala:2561)
[error]     at scala.Function1.$anonfun$compose$1(Function1.scala:44)
[error]     at sbt.internal.util.$tilde$greater.$anonfun$$u2219$1(TypeFunctions.scala:40)
[error]     at sbt.std.Transform$$anon$4.work(System.scala:67)
[error]     at sbt.Execute.$anonfun$submit$2(Execute.scala:269)
[error]     at sbt.internal.util.ErrorHandling$.wideConvert(ErrorHandling.scala:16)
[error]     at sbt.Execute.work(Execute.scala:278)
[error]     at sbt.Execute.$anonfun$submit$1(Execute.scala:269)
[error]     at sbt.ConcurrentRestrictions$$anon$4.$anonfun$submitValid$1(ConcurrentRestrictions.scala:178)
[error]     at sbt.CompletionService$$anon$2.call(CompletionService.scala:37)
[error]     at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
[error]     at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
[error]     at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
[error]     at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
[error]     at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
[error]     at java.base/java.lang.Thread.run(Thread.java:834)
[error] (update) sbt.librarymanagement.ResolveException: unresolved dependency: io.github.moglideveloper#base-plugin;0.1: not found
Invalid response.

以下是我们尝试解析 sbt 插件的简化 sbt 项目源代码:-

build.sbt :-

name := "ResolveBasePlugin"

build.properties:-

sbt.version=1.2.8

plugins.sbt :-

resolvers += Opts.resolver.mavenLocalFile
addSbtPlugin("io.github.moglideveloper" % "base-plugin" % "0.1")
addSbtPlugin("org.xerial.sbt" % "sbt-pack" % "0.13")

链接到简化插件:- https://github.com/moglideveloper/BasePlugin

链接到尝试解析基本插件的简化 sbt 项目 https://github.com/moglideveloper/ResolveCheck

Kindly suggest, what changes shall we do to BasePlugin, so that it can be resolved in sbt projects
that are using sbt.version=1.x
For eg :- 
sbt pack plugin is published with sbt.version=1.2.8, still it can be resolved
from sbt projects with sbt.version=1.4.5

https://github.com/xerial/sbt-pack/blob/master/project/build.properties

【问题讨论】:

【参考方案1】:

我认为您的project/plugins.sbt 中需要以下内容:

// bad: resolvers += Opts.resolver.mavenLocalFile

// good
resolvers += Resolver.mavenLocal

见Local Maven resolvers。

注意

你能解释一下这两者有什么区别吗?

Apache Ivy 和 Coursier 都有 Maven-layout 存储库和 Ivy-layout 存储库的解析器,因此在 sbt 中它们需要使用不同的类型来表达。

Resolver.mavenLocal 具有 MavenRepository 的静态类型,由 MavenCache 表示,并将转换为“支持插件的”IBiblioResolverfor Ivy。另一方面,Opts.resolver.mavenLocalFile 是一个文件系统解析器:

val mavenLocalFile = Resolver.file("Local Repository", userHome / ".m2" / "repository")(
  Resolver.defaultPatterns
)

这将转换为具有类似 Maven 模式的 Ivy 存储库。它可能适用于某些工件,但显然不适用于 sbt 插件。总的来说,我想不出必须使用Opts.resolver.mavenLocalFile的情况。

【讨论】:

你能解释一下这两者有什么区别吗?

以上是关于使用 sbt.version 1.2.8 发布到 nexus 的 Sbt 插件无法由使用 sbt.version >1.2.8 的 sbt 项目解决的主要内容,如果未能解决你的问题,请参考以下文章

SBT。解决 play sbt-plugin 的依赖关系

强制 sbt 重新加载整个构建定义

SBT:如何在多个任务中重用带有参数的代码?

测试 sbt 插件

迁移 Playframework 2.4.3 到 2.7.0 中的问题

为多项目中的子项目指定不同版本的 sbt?