Как включить плагин компилятора из libraryDependencies?

91
10

У меня есть плагин компилятора в зависимостях библиотеки и хотел бы включить его. Что-то вроде


autoCompilerPlugins := true

libraryDependencies += compilerPlugin(update.value.allModules.find(_.name contains "continuations-plugin").get)

scalacOptions += "-P:continuations:enable"


дает


/Users/luc/scala/release-sanity-check/build.sbt:20: error: A setting cannot depend on a task
libraryDependencies += compilerPlugin(update.value.allModules.find(_.name contains "continuations-plugin").get)
^

Могу ли я сделать это с помощью настраиваемой задачи?


val addContinuationsPlugin = taskKey[Unit]("Add continuations plugin")

addContinuationsPlugin := {
val plugin = update.value.allModules.find(_.name contains "continuations-plugin")
// add plugin?
}


Репозиторий, о котором идет речь: https://github.com/scala/scala-dist-smoketest

спросил(а) 2014-07-15T13:01:00+04:00 6 лет, 3 месяца назад
1
Решение
82

Вероятно, вы хотите что-то подобное (см. sbt API)


scalacOptions ++= {
val compileConfig = update.value.configurations.find(_.configuration == "compile").get
val pluginModule = compileConfig.modules.find(_.module.name contains "continuations-plugin").get
val pluginFile = pluginModule.artifacts.head._2
Seq(s"-Xplugin:${pluginFile.getCanonicalPath}", "-P:continuations:enable")
}

Метод compilePlugin предназначен для облегчения задачи при использовании Ivy для разрешения плагинов, и вы можете сделать это правильно.


Вариант № 2 должен попытаться обеспечить их транзитивную цепочку зависимостей конфигурации compiler-plugin->compiler-plugin между вашим проектом и проектом, где вы обнаружите плагин продолжения (где в конечном итоге будет ссылка compiler-plugin->default(compile)). Однако, не увидев дерево зависимостей, я не могу советовать вокруг варианта № 2 (который является более надежным методом).

ответил(а) 2014-07-15T18:54:00+04:00 6 лет, 3 месяца назад
71

Это довольно сложно, и я не знаю, могу ли я порекомендовать использовать этот метод помимо тестирования дыма от Typesafe, но здесь он идет. (Не пытайтесь делать это дома.)


Как вы и Яцек отметили, libraryDependencies, а также версия плагина должна быть известна статически во время компиляции сборки. Однако, поскольку сборка может быть построена с использованием мета-сборки, мы можем думать об этом как о времени выполнения метабактерий. Я продемонстрировал это в своем ответе на Как распространять значения версии между project/plugins.sbt и project/Build.scala?


Таким образом, используя sbt-buildinfo, мы можем поднять значения задачи мета-сборки в значение настройки правильной сборки. Следующий вопрос заключается в том, как мы можем найти версию плагина продолжения в мета-сборке. Опять же, это трюк, но мы можем создать фиктивную конфигурацию Ivy в мета-сборке, добавить туда scala -dist и выкинуть номер версии из externalDependencyClasspath in BogusConfig. Это изменение отправляется как # 1.


проект/проект/buildinfo.sbt


addSbtPlugin("com.eed3si9n" % "sbt-buildinfo" % "0.3.2")

проект/проект/Dependencies.scala

package metabuild

import sbt._

object Dependencies {
def scalaDistVersion = sys.props("project.version")
}

object Configs {
lazy val BogusConfig = config("bogus")
}


Проект /plugins.sbt


import metabuild.Dependencies._
import metabuild.Configs._

lazy val continuationPluginVersion = taskKey[String]("version of the continuation plugin")

lazy val build = (project in file(".")).
configs(BogusConfig).
settings(inConfig(BogusConfig)(Defaults.configSettings): _*).
settings(buildInfoSettings: _*).
settings(addSbtPlugin("com.typesafe.sbt" % "sbt-git" % "0.6.4"): _*).
settings(
resolvers += "jgit-repo" at "http://download.eclipse.org/jgit/maven",
libraryDependencies += "org.scala-lang" % "scala-dist" % scalaDistVersion % BogusConfig,
sourceGenerators in Compile <+= buildInfo,
buildInfoKeys := Seq[BuildInfoKey](
"scalaDistVersion" -> scalaDistVersion,
continuationPluginVersion
),
buildInfoPackage := "metabuild",
continuationPluginVersion := {
val bogusClasspath = (externalDependencyClasspath in BogusConfig).value
val f = (bogusClasspath find { _.data.getName contains "continuations-plugin" }).get.data
f.getName.replaceAllLiterally("scala-continuations-plugin_" + scalaDistVersion + "-", "").replaceAllLiterally(".jar", "")
}
)


build.sbt


import metabuild.BuildInfo._

// versionWithGit

version := scalaDistVersion

scalaVersion := version.value

libraryDependencies += "org.scala-lang" % "scala-dist" % version.value

autoCompilerPlugins := true

libraryDependencies +=
compilerPlugin("org.scala-lang.plugins" % ("scala-continuations-plugin_" + version.value) % continuationPluginVersion)

scalacOptions += "-P:continuations:enable"

ответил(а) 2014-07-15T18:57:00+04:00 6 лет, 3 месяца назад
58

"У меня есть плагин компилятора в зависимостях библиотек и хотел бы добавить его включить".


Следуя Поддержка плагинов компилятора из официальной документации sbt, вы должны включить поддержку плагинов компилятора в build.sbt следующим образом:


autoCompilerPlugins := true

Затем вы используете addCompilerPlugin, чтобы добавить плагин как зависимость (до libraryDependencies) в области plugin->default(compile).


addCompilerPlugin("org.scala-tools.sxr" %% "sxr" % "0.3.0")

С помощью настроек вы можете настроить плагин:


scalacOptions :=
scalacOptions.value :+ ("-Psxr:base-directory:" + (scalaSource in Compile).value.getAbsolutePath)

ответил(а) 2014-07-15T13:12:00+04:00 6 лет, 3 месяца назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема