1. 更新报告

更新报告 

update 和相关任务生成类型为 sbt.UpdateReport 的值。此数据结构提供了有关已解析配置、模块和工件的信息。在顶层,UpdateReport 为每个已解析配置提供了类型为 ConfigurationReport 的报告。ConfigurationReport 为给定配置解析的每个模块提供报告(类型为 ModuleReport)。最后,ModuleReport 列出了每个成功检索的 Artifact 及其检索到的 File,以及无法下载的 Artifact。此缺少的 Artifact 列表在 update 中始终为空,如果它不为空,update 将失败。但是,它可能在 updateClassifiersupdateSbtClassifers 中不为空。

过滤报告并获取工件 

UpdateReport 的典型用法是检索与过滤器匹配的文件列表。UpdateReport => RichUpdateReport 类型的转换隐式地为 UpdateReport 提供这些方法。过滤器由 DependencyFilterConfigurationFilterModuleFilterArtifactFilter 类型定义。使用这些过滤器类型,您可以按配置名称、模块组织、名称或修订版以及工件名称、类型、扩展名或分类器进行过滤。

相关方法(隐式在 UpdateReport 上)是

def matching(f: DependencyFilter): Seq[File]

def select(configuration: ConfigurationFilter = ...,
  module: ModuleFilter = ...,
  artifact: ArtifactFilter = ...): Seq[File]

select 的任何参数都可以省略,在这种情况下,所有值都允许用于相应的组件。例如,如果未指定 ConfigurationFilter,则所有配置都将被接受。以下将讨论各个过滤器类型。

过滤器基础 

配置、模块和工件过滤器通常通过将 NameFilter 应用于 ConfigurationModuleIDArtifact 的每个组件来构建。基本 NameFilter 隐式地从字符串构造,其中 * 被解释为通配符。

import sbt._
// each argument is of type NameFilter
val mf: ModuleFilter = moduleFilter(organization = "*sbt*",
  name = "main" | "actions", revision = "1.*" - "1.0")

// unspecified arguments match everything by default
val mf: ModuleFilter = moduleFilter(organization = "net.databinder")

// specifying "*" is the same as omitting the argument
val af: ArtifactFilter = artifactFilter(name = "*", `type` = "source",
  extension = "jar", classifier = "sources")

val cf: ConfigurationFilter = configurationFilter(name = "compile" | "test")

或者,这些过滤器,包括 NameFilter,可以直接由适当的谓词(返回布尔值的单参数函数)定义。

import sbt._

// here the function value of type String => Boolean is implicitly converted to a NameFilter
val nf: NameFilter = (s: String) => s.startsWith("dispatch-")

// a Set[String] is a function String => Boolean
val acceptConfigs: Set[String] = Set("compile", "test")
// implicitly converted to a ConfigurationFilter
val cf: ConfigurationFilter = acceptConfigs

val mf: ModuleFilter = (m: ModuleID) => m.organization contains "sbt"

val af: ArtifactFilter = (a: Artifact) => a.classifier.isEmpty

ConfigurationFilter 

配置过滤器本质上包装了一个 NameFilter,并由 configurationFilter 方法显式构造

def configurationFilter(name: NameFilter = ...): ConfigurationFilter

如果省略参数,则过滤器将匹配所有配置。类型为 String => Boolean 的函数隐式地可转换为 ConfigurationFilter。与 ModuleFilterArtifactFilterNameFilter 一样,&|- 方法可用于组合 ConfigurationFilter

import sbt._
val a: ConfigurationFilter = Set("compile", "test")
val b: ConfigurationFilter = (c: String) => c.startsWith("r")
val c: ConfigurationFilter = a | b

(这里的显式类型是可选的。)

ModuleFilter 

模块过滤器由三个 NameFilter 定义:一个用于组织,一个用于模块名称,一个用于修订版。每个组件过滤器都必须匹配才能匹配整个模块过滤器。模块过滤器由 moduleFilter 方法显式构造

def moduleFilter(organization: NameFilter = ..., name: NameFilter = ..., revision: NameFilter = ...): ModuleFilter

省略的参数不会对匹配做出贡献。如果所有参数都被省略,则过滤器将匹配所有 ModuleID。类型为 ModuleID => Boolean 的函数隐式地可转换为 ModuleFilter。与 ConfigurationFilterArtifactFilterNameFilter 一样,&|- 方法可用于组合 ModuleFilter

import sbt._
val a: ModuleFilter = moduleFilter(name = "dispatch-twitter", revision = "0.7.8")
val b: ModuleFilter = moduleFilter(name = "dispatch-*")
val c: ModuleFilter = b - a

(这里的显式类型是可选的。)

ArtifactFilter 

工件过滤器由四个 NameFilter 定义:一个用于名称,一个用于类型,一个用于扩展名,一个用于分类器。每个组件过滤器都必须匹配才能匹配整个工件过滤器。工件过滤器由 artifactFilter 方法显式构造

def artifactFilter(name: NameFilter = ..., `type`: NameFilter = ...,
  extension: NameFilter = ..., classifier: NameFilter = ...): ArtifactFilter

类型为 Artifact => Boolean 的函数隐式地可转换为 ArtifactFilter。与 ConfigurationFilterModuleFilterNameFilter 一样,&|- 方法可用于组合 ArtifactFilter

import sbt._
val a: ArtifactFilter = artifactFilter(classifier = "javadoc")
val b: ArtifactFilter = artifactFilter(`type` = "jar")
val c: ArtifactFilter = b - a

(这里的显式类型是可选的。)

DependencyFilter 

DependencyFilter 通常通过使用 &&||-- 将其他 DependencyFilter 组合在一起进行构造。配置、模块和工件过滤器本身就是 DependencyFilter,可以作为 DependencyFilter 直接使用,也可以构建 DependencyFilter。请注意,DependencyFilter 组合方法的符号是加倍的,以将其与配置、模块和工件的更具体过滤器的组合器区分开来。这些双字符方法将始终返回 DependencyFilter,而单字符方法则保留更具体的过滤器类型。例如

import sbt._

val df: DependencyFilter =
  configurationFilter(name = "compile" | "test") &&
  artifactFilter(`type` = "jar") ||
  moduleFilter(name = "dispatch-*")

在这里,我们使用 &&|| 将单个组件过滤器组合成依赖过滤器,然后可以将其提供给 UpdateReport.matches 方法。或者,可以使用 UpdateReport.select 方法,该方法等效于使用其参数与 && 组合来调用 matches