在 SBT 0.13 中惯用地定义动态任务? [英] Idiomatically defining dynamic tasks in SBT 0.13?

查看:19
本文介绍了在 SBT 0.13 中惯用地定义动态任务?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在将 SBT 插件从 0.12 移至 0.13.在我的插件的不同点,我将一组动态任务安排到 SBT 构建图上.

I'm moving an SBT plugin from 0.12 over to 0.13. At various points in my plugin I schedule a dynamic set of tasks onto the SBT build graph.

下面是我的旧代码.这仍然是表达这一点的惯用方式,还是可以利用宏使一切更漂亮?

Below is my old code. Is this still the idiomatic way to express this, or is it possible to leverage the macros to make everything prettier?

import sbt._
import Keys._

object Toplevel extends Build
{
    lazy val ordinals = taskKey[Seq[String]]("A list of things")
    lazy val times = taskKey[Int]("Number of times to list things")
    lazy val inParallel = taskKey[Seq[String]]("Strings to log in parallel")

    lazy val Foo = Project( id="Foo", base=file("foo"),
        settings = Defaults.defaultSettings ++ Seq(
            scalaVersion    := "2.10.2",

            ordinals := Seq( "First", "Second", "Third", "Four", "Five" ),

            times := 3,

            inParallel <<= (times, ordinals, streams) flatMap
            { case (t, os, s) =>
                os.map( o => toTask( () =>
                {
                    (0 until t).map( _ => o ).mkString(",")
                } ) ).join
            }

        )
    )
}

为完全人为的例子道歉!

Apologies for the entirely contrived example!

编辑

因此,考虑到 Mark 的建议,我有以下更整洁的代码:

So, taking Mark's advice into account I have the following tidier code:

import sbt._
import Keys._

object Toplevel extends Build
{
    lazy val ordinals = taskKey[Seq[String]]("A list of things")
    lazy val times = taskKey[Int]("Number of times to list things")
    lazy val inParallel = taskKey[Seq[String]]("Strings to log in parallel")

    def parTask = Def.taskDyn
    {
        val t = times.value
        ordinals.value.map(o => ordinalTask(o, t)).join
    }

    def ordinalTask(o: String, t: Int) = Def.task
    {
        (0 until t).map(_ => o).mkString(",")
    }

    lazy val Foo = Project( id="Foo", base=file("foo"),
        settings = Defaults.defaultSettings ++ Seq(
            scalaVersion    := "2.10.2",

            ordinals := Seq( "First", "Second", "Third", "Four", "Five" ),

            times := 3,

            inParallel := parTask.value
        )
    )
}

这似乎快到了,但构建失败:

This seems to be nearly there, but fails the build with:

[error] /home/alex.wilson/tmp/sbt0.13/project/build.scala:13: type mismatch;
[error]  found   : sbt.Def.Initialize[Seq[sbt.Task[String]]]
[error]  required: sbt.Def.Initialize[sbt.Task[?]]
[error]         ordinals.value.map(o => ordinalTask(o, t)).join

推荐答案

您可以使用 Def.taskDyn,它为 flatMap 提供了新的语法.与 Def.task 的区别在于预期的返回类型是任务 Initialize[Task[T]] 而不仅仅是 T.翻译你的例子,

You can use Def.taskDyn, which provides the new syntax for flatMap. The difference from Def.task is that the expected return type is a task Initialize[Task[T]] instead of just T. Translating your example,

inParallel := parTask.value

def parTask = Def.taskDyn {
   val t = times.value
   ordinals.value.map(o => ordinalTask(o, t)).joinWith(_.join)
}

def ordinalTask(o: String, t: Int) = Def.task {
   (0 until t).map(_ => o).mkString(",")
}

这篇关于在 SBT 0.13 中惯用地定义动态任务?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆