2012-01-21 14 views
18

Tôi muốn một chương trình tôi đang xây dựng có thể báo cáo phiên bản riêng của mình khi chạy (ví dụ: scala myprog.jar --version). Theo truyền thống trong một dự án maven, tôi sẽ sử dụng lọc tài nguyên (pom.xml -> file.properties -> đọc giá trị khi chạy). Tôi biết có sbt-filter-plugin để mô phỏng chức năng này, nhưng tôi tò mò nếu có một cách tiêu chuẩn/ưa thích/thông minh hơn để làm điều này trong SBT.SBT bao gồm số phiên bản trong chương trình

tl; dr làm cách nào để đọc số phiên bản được xác định trong build.sbt khi chạy?

+0

Cách thành ngữ phù hợp để thực hiện việc này ngày nay là thông qua sbt-buildinfo https://github.com/sbt/sbt-buildinfo/. –

Trả lời

19

Update ...

https://github.com/ritschwumm/xsbt-reflect (nêu trên) là lỗi thời, nhưng có SBT công cụ phát hành mát mẻ này có thể tự động quản lý phiên bản và nhiều hơn nữa: https://github.com/sbt/sbt-release.

Ngoài ra, nếu bạn muốn có một sửa chữa nhanh chóng bạn có thể nhận được phiên bản từ manifest như thế này:

val version: String = getClass.getPackage.getImplementationVersion 

Giá trị này sẽ bằng version thiết lập trong dự án của bạn mà bạn thiết lập hoặc trong build.sbt hoặc Build.scala.

Cập nhật Một ...

Buildinfo SBT plugin có thể tạo ra một lớp học với số phiên bản dựa trên build.sbt:

/** This object was generated by sbt-buildinfo. */ 
case object BuildInfo { 
    /** The value is "helloworld". */ 
    val name: String = "helloworld" 
    /** The value is "0.1-SNAPSHOT". */ 
    val version: String = "0.1-SNAPSHOT" 
    /** The value is "2.10.3". */ 
    val scalaVersion: String = "2.10.3" 
    /** The value is "0.13.2". */ 
    val sbtVersion: String = "0.13.2" 
    override val toString: String = "name: %s, version: %s, scalaVersion: %s, sbtVersion: %s" format (name, version, scalaVersion, sbtVersion) 
} 

Xem các tài liệu về cách kích hoạt nó ở đây: https://github.com/sbt/sbt-buildinfo/.

+2

Thật không may, điều này mang lại một 'null' cho tôi. sbt 0.13.8, JDK 8, Scala 2.11.7 – akauppi

+0

Bạn đã đặt 'phiên bản' chính xác trong SBT chưa? –

+0

Có, nó hiển thị trong tên tệp jar đầu ra, v.v. Nhưng dự án không tạo ra bất kỳ maven nào, nó là một chương trình thực thi độc lập. Tôi giả định đây là lý do nó sẽ không nhận được các phiên bản thực hiện/đặc điểm kỹ thuật vv Bất kỳ con trỏ được chào đón - Tôi không phải từ một nền Java vì vậy những cảm thấy một chút overengineered cho tôi. :) – akauppi

7

Sử dụng plugin xsbt-reflect. Nó sẽ tạo ra một tập tin nguồn có chứa, trong số những thứ khác, số phiên bản dự án.

+0

Cảm ơn, trông giống như một giải pháp rất tốt –

+0

Làm việc như một sự quyến rũ, cảm ơn một lần nữa. –

1

Tôi đã kết thúc tạo hệ thống xây dựng (tôi sử dụng Makefile trên đầu trang sbt) chuẩn bị tệp src/main/resources/version.txt để Scala đọc.

Trong Makefile:

$(RESOURCES_VERSION): build.sbt 
    grep "^version := " $< | cut -f2 -d\" > [email protected] 

Trong Scala:

val version: String = { 
    val src = Source.fromURL(getClass.getResource("/version.txt")) 
    src.getLines.next // just take the first line 
} 

này làm việc cho tôi.

Thật lạ lùng rằng tính năng cần thiết như vậy (tôi nghĩ) không dễ dàng có trong Scala. Một plugin rất đơn giản sbt chỉ dành cho điều này sẽ được hoan nghênh.

+0

Nó dễ dàng có sẵn trong vanilla sbt, xem câu trả lời của tôi. – Tvaroh

0

Nói chung, mà không cần bất kỳ plugin, bạn có thể làm một cái gì đó như thế này:

sourceGenerators in Compile += Def.task { 
    val file = (sourceManaged in Compile).value/"foo"/"bar"/"BuildInfo.scala" 

    IO.write(
    file, 
    s"""package foo.bar 
     |object BuildInfo { 
     | val Version = "${version.value}" 
     |}""".stripMargin 
) 

    Seq(file) 
}.taskValue 

Và sau đó làm với foo.bar.BuildInfo.Version liên tục bất cứ điều gì bạn muốn.

Hoặc tổng quát hơn:

def generateBuildInfo(packageName: String, 
         objectName: String = "BuildInfo"): Setting[_] = 
    sourceGenerators in Compile += Def.task { 
    val file = 
     packageName 
     .split('.') 
     .foldLeft((sourceManaged in Compile).value)(_/_)/s"$objectName.scala" 

    IO.write(
     file, 
     s"""package $packageName 
     |object $objectName { 
     | val Version = "${version.value}" 
     |}""".stripMargin 
    ) 

    Seq(file) 
    }.taskValue 

Ví dụ:

settings(generateBuildInfo("foo.bar")) 

Bạn thậm chí có thể thay đổi điều này để vượt qua thuộc tính đối tượng như một Map[String, String] và tạo ra các đối tượng thích hợp.