scala - SBT中任务和命令的异同

标签 scala sbt

我最近收到指示不要混淆 this answer 上的任务和命令,这让我首先意识到甚至存在差异。在我的研究过程中,困惑更加明显,我必须承认我无法清楚地将两者分开!我认为主要的问题是术语经常被同义地使用,但概念是不同的、高度相关的并且在某些方面非常相似。
阅读文档并没有让我很满意。我不想在 sbt 文档中明确显示问题,所以不要误会我的意思,但我希望你看到我目前的进展。 我在旅途中将我的问题标记为粗体,并在其前面添加了一个数字。

研究

我咨询的第一个资源是 Tasks and Commands文档中的部分,该部分仅指向入门指南。

入门

入门指南并没有真正解释这方面的差异。
特别是Defining tasks and settings部分似乎引入了更多的困惑,类型之间的目的地; Setting[T] , Setting[Task[T]] , Task[T]以及 key 及其对应类型的术语。

A TaskKey[T] is said to define a task. Tasks are operations such as compile or package. They may return Unit (Unit is Scala for void), or they may return a value related to the task, for example package is a TaskKey[File] and its value is the jar file it creates.



这有点古怪,但现在还可以,因此任务是 TaskKey结果类型为 T 的实例.

Each time you start a task execution, for example by typing compile at the interactive sbt prompt, sbt will re-run any tasks involved exactly once.



所以任何任务都可以在 sbt 提示符下使用。那么命令的区别在哪里呢?在其他部分,两者似乎是同义词,例如 here .栏目More About Settings进一步描述:

Remember that some settings describe tasks, so this approach also creates dependencies between tasks.



因此任务可能相互依赖,由设置引入。

A plugin extends the build definition, most commonly by adding new settings. The new settings could be new tasks. For example, a plugin could add a codeCoverage task which would generate a test coverage report.



插件可能会使用设置引入新任务。

Also remember from .sbt build definition that a setting has a fixed value until project reload, while a task is re-computed for every “task execution” (every time someone types a command at the sbt interactive prompt or in batch mode).



这让我觉得命令只是在 sbt 提示符下输入的东西,或者使用批处理模式直接输入到终端。此外,它产生了一种想法,即命令仅充当每个任务的浅层前端。 #1 每个任务都有对应的命令吗?

By defining triggered plugins, auto plugins can be used as a convenient way to inject custom tasks and commands across all subprojects.



在这里,我认为命令可以单独设置 - 类似于任务。然而该部分Running Commands讨论为命令或任务创建别名,但没有说明任何有关任务的信息。我再次觉得这些概念可能是相同的,尽管我知道两者是不同的。

任务

以下是根据 Tasks 与任务相关的功能列表页:
  • 通过与设置系统集成,可以像设置一样轻松灵活地添加、删除和修改任务。
  • 输入任务使用解析器组合子来定义其参数的语法。这允许以与命令相同的方式灵活的语法和制表符完成。
  • 任务产生值(value)。其他任务可以通过在任务定义中调用值来访问任务的值。
  • 动态改变任务图的结构是可能的。可以根据另一个任务的结果将任务注入(inject)到执行图中。
  • 有一些方法可以处理任务失败,类似于 try/catch/finally。
  • 每个任务都可以访问自己的 Logger,默认情况下,该 Logger 以比最初打印到屏幕上更详细的级别保存该任务的日志记录。

  • 在功能之上,它进一步说:

    Settings are evaluated at project load time. Tasks are executed on demand, often in response to a command from the user.



    好的,所以有些任务可能会通过其他方式启动。

    命令

    最后是 command页面指​​出:

    A “command” looks similar to a task: it’s a named operation that can be executed from the sbt console.



    所以现在我认为任何来自 sbt 提示或批处理的对指定任务或命令的调用都被称为命令。无论命令是指向任务还是命令实例。 #2 因此,为了减少歧义,区分定义和调用级别是否有意义? 例如:在调用级别,一切都是命令,但在定义级别,这是一个 CommandTaskKey实例。

    这是一段代码,显示了命令定义的一般结构:
    val action: (State, T) => State = ???
    val parser: State => Parser[T] = ???
    val command: Command = Command("name")(parser)(action)
    

    所以commandaction是一种状态转换,使其在函数式编程方面具有高度的可组合性。相比之下,任务是 TaskKey[T]实例更像是一个返回 T 类型结果的简单函数.功能列表中的第 3 点指出任务会产生值,这让我认为任务更像是纯粹的函数,只会产生一些小的副作用,如第 6 点所述的日志记录,除了返回类型为 Unit 的任务。 .

    However, a command’s implementation takes as its parameter the entire state of the build (represented by State) and computes a new State. This means that a command can look at or modify other sbt settings, for example. Typically, you would resort to a command when you need to do something that’s impossible in a regular task.



    所以我认为命令在某些情况下会有些优越。然后我问自己:任务和命令是否共享关于任务功能列表的相同功能子集,如显而易见的第 2 点?第 1 点指出,由于设置系统的集成,可以对设置进行任意修改,对命令来说不是这样吗?第 4、5 和 6 点相同。 #3 有人可以澄清这一点,尤其是限制,并给出我应该客观地更喜欢使用命令而不是任务的原因,或者什么时候不应该使用(反)示例?

    最佳答案

    尽可能尝试使用任务。它们更容易理解,也更容易编写。

    从文档:

    Typically, you would resort to a command when you need to do something that’s impossible in a regular task.



    如果没有指定任务的限制是什么,那当然无济于事。然而,我个人认为它的意思是:如果你想操纵 state在构建中,您可以使用命令。

    这方面的一个例子是当您想要使用不同的设置运行任务时。

    任务使您可以访问其他设置和任务,命令还可以让您访问状态并允许您对其进行操作。然而,这是以其他开发人员不熟悉和增加复杂性为代价的。

    在某些情况下,某些内容既可以表示为任务,也可以表示为命令。在这里,我会采取选择一种感觉更容易的方法。

    关于scala - SBT中任务和命令的异同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33187448/

    相关文章:

    java - Scala Futures 和 java 8 CompletableFuture

    image - 单色位图

    scala - Scala 项目中使用 sbt 与 maven 的优缺点

    arrays - Scala 中的多重赋值而不使用数组?

    斯卡拉 3 : Finding functions with the given annotation

    unit-testing - 如何减少specs2中的故障显示

    spring - 从 Maven 切换到 sbt

    scala - 如何在scaladoc中生成到标准库类型的链接?

    scala - sbt - 将非托管资源添加到控制台

    scala - 有没有一种简单的方法可以用 Dotty 编译一个 sbt 项目?