2011-11-30 37 views
12

Giả sử một anh chàng trong công ty của tôi có một dự án sbt gọi là commons đó là mục đích khá chung chung. Dự án này được định nghĩa theo cách sbt truyền thống: trong thư mục chính với định nghĩa xây dựng trong tệp project/Build.scala.Làm thế nào để xác định rằng để xây dựng dự án Một dự án B khác phải được xây dựng đầu tiên?

Bây giờ, một số người khác đang phát triển một dự án có tên là databinding phụ thuộc vào commons. Chúng tôi muốn xác định dự án này theo cùng một cách, với project/Build.scala.

Chúng tôi đã bố trí thư mục sau:

dev/ 
    commons/ 
    src/ 
     *.scala files here... 
    project/ 
     Build.scala 
    databinding/ 
    src/ 
     *.scala files here... 
    project/ 
     Build.scala 

Làm thế nào tôi có thể xác định rằng databinding đòi hỏi commons được xây dựng đầu tiên và sử dụng các tập tin lớp đầu ra?

tôi đọc Multi-project builds, và đã đưa ra những điều sau đây để định nghĩa xây dựng của databinding:

object MyBuild extends Build { 

    lazy val root = Project(id = "databinding", base = file(".")) settings (
    // ... omitted 
) dependsOn (commons) 

    lazy val common = Project(id = "commons", 
    base = file("../commons") 
) 

} 

Trừ nó không hoạt động: SBT không thích .. và ném một AssertionError. Rõ ràng, commons phải là một thư mục bên trong databinding. Nhưng hai dự án này được lưu giữ trong kho lưu trữ git riêng biệt, mà chúng tôi không thể làm tổ.

Phụ thuộc này có thể được chỉ định đúng cách như thế nào?

Trả lời

12

Bạn cần xác định nhiều dự án trong một dự án gốc (hoặc bất kỳ tên nào nhưng tên này phù hợp) sẽ được xác định trong dev/project/Build.scala.

object RootBuild extends Build { 
    lazy val root = Project(id = "root", base = file(".")) 
    .settings(...) 
    .aggregate(commons, databinding) 

    lazy val commons = Project(id = "commons", base = file("commons")) 
    .settings(...) 

    lazy val databinding = Project(id = "databinding", base = file("databinding")) 
    .settings(...) 
    .dependsOn(commons) 
} 

một điều nữa, SBT không hỗ trợ *.scala tệp cấu hình trong tiểu dự án. Điều này có nghĩa là bạn sẽ phải di chuyển cấu hình bạn đã thực hiện trên commons/project/Build.scaladatabinding/project/Build.scala vào tương ứng commons/build.sbtdatabinding/build.sbt.

Nếu một số cấu hình của bạn không phù hợp với tệp định nghĩa .sbt, bạn sẽ phải thêm chúng vào thư mục gốc project/Build.scala. Rõ ràng, các cài đặt được xác định trong root Build.scala có sẵn trong *.sbt tệp.

+0

Cảm ơn rất nhiều lời giải thích, David. Điều này có vẻ kỳ lạ, có phải vì các dự án khác sử dụng dự án 'commons' của tôi, nó không thể có định nghĩa đầy đủ trong tệp' .scala'? –

+0

Và, có một sự thay thế nào không - ví dụ: thêm trình phân giải tìm kiếm các lọ được tạo bởi các dự án mà nó phụ thuộc vào? –

+0

Về câu hỏi đầu tiên của bạn, đó là một hạn chế SBT ngăn bạn sử dụng '*.tệp scala' để xác định các tiểu dự án. Tôi nghĩ rằng đó là một hạn chế do cách SBT sáp nhập các tệp định nghĩa dự án. May mắn thay, các tệp '* .sbt' sẽ có thể truy cập các thông số, cài đặt ... từ dự án gốc của bạn' Build.scala'. Bạn cũng có thể xem xét như bạn đề cập đến nó trong bình luận thứ hai để xuất bản của bạn 'phổ biến' trong địa phương (xuất bản địa phương) ví dụ và các resolver nên lấy nó. Hãy cẩn thận để thêm 'isChanging()' vào định nghĩa phụ thuộc nếu bạn muốn sử dụng hệ thống SNAPSHOT. Hy vọng điều này sẽ giúp. – David

1

Bạn có thể có hai dự án riêng biệt và chỉ xuất bản một trong các dự án đó tại địa phương, thêm nó dưới dạng phụ thuộc thư viện thông thường cho người khác.

10

Bạn nên sử dụng RootProject (trong trường hợp đề cập đến dự án gốc của dự án khác) hoặc ProjectRef (trong trường hợp đề cập đến tiểu dự án của một dự án khác).

Đây là một mẫu của việc sử dụng RootProject:

 lazy val commons = RootProject(file("../commons")) 
     lazy val root = Project(id = "databinding", base = file(".")) settings (...) dependsOn (commons) 

Và đây là các mẫu cho việc sử dụng ProjectRef

 lazy val commons = ProjectRef(file("../commons"), "sub-project") 
     lazy val root = Project(id = "databinding", base = file(".")) settings (...) dependsOn (commons) 
+0

Đây có phải là 'RootProject' mới không? API mới này có làm mất hiệu lực giải pháp được đề xuất của David không? –

+0

Có vẻ như vậy. Không, nhưng tôi muốn nói nó đơn giản hơn một chút –

+1

Tôi không thể hiểu được cách câu trả lời được phê duyệt có thể đã làm việc cho OP mà không di chuyển đánh bại mục đích của hai dự án độc lập. Họ sẽ không sau khi di chuyển vì dự án gốc. –

Các vấn đề liên quan