传递代替常春藤模块

时间:2016-05-24 10:48:41

标签: scala sbt ivy

我以编程方式(在SBT的上下文中)使用常春藤,我需要 能够用一个传递方式替换一小组模块 兼容集,具有不同的组织,但共享 工件名称,修订等。

举一个具体的例子,我想替换,

org.scala-lang#scala-reflect;2.11.8

用,

org.typelevel#scala-reflect;2.11.8

依赖图中的任何地方。请注意,我只想添加一个 对org.typelevel的依赖#scala-reflect; 2.11.8如果有的话 对org.scala-lang的依赖#scala-reflect; 2.11.8在某处 图表(我不提前知道),所以还不够 无条件地排除org.scala-lang模块并包含 org.typelevel one。

这可能吗?如果是,指向必要机制的指针就是 非常欢迎。如果不是,那么也可以提供解决方法的建议 非常欢迎。

2 个答案:

答案 0 :(得分:0)

虽然这不是最干净的解决方案,但我认为您可以通过劫持项目解析器(负责解决SBT中的项目间依赖关系)来实现此目的。

构建文件中的某处:

// ...
.settings(
  projectResolver <<= (projectDescriptors, streams) map { (m, s) =>
    new RawRepository(new ProjectResolver("custom-resolver", m) {
      import org.apache.ivy.core.module.descriptor.DependencyDescriptor
      import org.apache.ivy.core.resolve.ResolveData
      import org.apache.ivy.core.resolve.ResolvedModuleRevision

      override def getDependency(dd: DependencyDescriptor, data: ResolveData): ResolvedModuleRevision = {
        s.log.info("Resolving " + dd.getDependencyId.getName)

        // adjust your dependency descriptor and possibly resolve
        // from another source?

        super.getDependency(dd, data)
      }
    })
  }
)

这个新项目解析器可以调整某些依赖描述符,然后针对常规解析器链解决它们... 我认为。您可能必须覆盖其他一些方法。

答案 1 :(得分:0)

这可以使用常春藤DependencyDescriptorMediator来完成。以下内容将执行module类型DefaultModuleDescriptor的问题中描述的重写,

class OverrideScalaMediator(scalaOrganization: String, scalaVersion: String)
  extends DependencyDescriptorMediator {
  def mediate(dd: DependencyDescriptor): DependencyDescriptor = {
    val transformer =
      new NamespaceTransformer {
        def transform(mrid: ModuleRevisionId): ModuleRevisionId = {
          if (mrid == null) mrid
          else
            mrid.getName match {
              case name @ "scala-reflect" =>
                ModuleRevisionId.newInstance(
                  scalaOrganization, name, mrid.getBranch, scalaVersion,
                  mrid.getQualifiedExtraAttributes
                )
              case _ => mrid
            }
        }

        def isIdentity: Boolean = false
      }

    DefaultDependencyDescriptor.transformInstance(dd, transformer, false)
  }
}

val mediator = new OverrideScalaMediator("org.typelevel", version)
module.addDependencyDescriptorMediator(
  new ModuleId("org.scala-lang", "*"), ExactPatternMatcher.INSTANCE, mediator
)

您可以在SBT here中看到这一点。