2014-04-10 27 views
5

Nếu tôi đã viết một số mã nguồn trong dự án xây dựng định nghĩa của tôi (trong/project/src/main/scala) trong SBT. Bây giờ tôi muốn sử dụng các lớp này cũng trong dự án tôi đang xây dựng. Có cách nào tốt nhất không? Hiện tại tôi đã tạo một Tác vụ tùy chỉnh sao chép các tệp .scala qua.Cách chia sẻ mã giữa dự án và dự án xây dựng định nghĩa trong SBT

+1

Bạn có thể sao lưu và giải thích lý do tại sao bạn đang cố gắng để làm điều đó? Tôi không nghĩ rằng thực sự có thể cho bất cứ ai đề xuất một "thực hành tốt nhất" về điều này trừ khi bạn cho chúng tôi biết thêm về mục tiêu của bạn và suy nghĩ của bạn đã dẫn bạn đến thời điểm này. Về cơ bản, những gì bạn mô tả không có vẻ như thực hành tốt với tôi cả. Nhưng nếu tôi hiểu mục tiêu của bạn tốt hơn, có lẽ phản ứng của tôi sẽ thay đổi. –

+0

@SethTisue: Tôi đã viết một Tác vụ tuần tự hóa một đồ thị của các đối tượng Scala bằng cách sử dụng Kryo và viết chúng dưới dạng tệp vào đường dẫn lớp của dự án. Biểu đồ dựa trên các tệp XML lớn và phân tích cú pháp chúng là thứ mà tôi không muốn thực hiện khi chạy. Bây giờ khi ứng dụng của tôi bắt đầu, tôi deserializing trở lại đồ thị đối tượng từ các tập tin mà yêu cầu quyền truy cập vào các tập tin lớp học. Một trường hợp sử dụng tiềm năng khác là khi bạn đã viết các lớp tiện ích trong dự án xây dựng định nghĩa mà bạn muốn tái sử dụng trong dự án của mình. – reikje

Trả lời

1

Bạn có thể thực hiện công việc sau không? Đặt mã nguồn cho các lớp được đề cập sẽ là một phần của dự án của bạn, không phải là một phần của định nghĩa xây dựng của bạn; "nhiệm vụ tuần tự hóa một đồ thị của các đối tượng Scala bằng cách sử dụng Kryo và viết chúng dưới dạng tệp vào đường dẫn lớp của dự án" phần âm thanh như một công việc hoàn hảo cho resourceGenerators (xem http://www.scala-sbt.org/0.13.2/docs/Howto/generatefiles.html). Sau đó, vấn đề còn lại duy nhất là làm thế nào để tham khảo các lớp được biên dịch từ trình tạo tài nguyên của bạn. Tôi không quen với Kryo. Để sử dụng nó, bạn có cần phải có các lớp được biên dịch trên classpath tại thời điểm máy phát của bạn được biên dịch hay chúng chỉ cần trên classpath khi chạy? Nếu sau này là đủ, đó là dễ dàng hơn. Bạn có thể lấy trình nạp lớp từ khóa testLoader in Test, tải lớp và khởi tạo một số đối tượng thông qua sự phản chiếu và sau đó gọi Kryo.

Nếu bạn thực sự cần các lớp được biên dịch trên đường dẫn lớp khi trình tạo tài nguyên của bạn được biên dịch, thì bạn có vấn đề về gà và trứng khi không thể biên dịch cho đến khi dự án được biên dịch, nhưng tất nhiên dự án không thể được biên dịch trước khi xây dựng định nghĩa đã được biên soạn, một trong hai. Trong trường hợp đó, dường như tôi không có lựa chọn nào khác ngoài:

1) cách giải quyết bạn đang thực hiện ("thực hành tốt nhất" trong trường hợp này sẽ bao gồm việc sử dụng sourceGenerators để sao chép nguồn ra khỏi định nghĩa xây dựng của bạn và vào target/src_managed)

2) đặt các lớp học được đề cập trong một dự án riêng biệt và phụ thuộc vào nó từ cả bản dựng của bạn và dự án của bạn. đây là giải pháp sạch nhất tổng thể, nhưng bạn có thể coi nó quá nặng.

Hy vọng điều này sẽ hữu ích. Quan tâm đến việc xem ý kiến ​​của người khác về vấn đề này.

+0

Tôi đã làm theo đề xuất thứ hai của bạn ngay bây giờ. Điều này hoạt động khá tốt. – reikje

3

Có vẻ như các cơ chế gián tiếp không cần thiết.

unmanagedSourceDirectories in Compile += baseDirectory.value/"project/src/main" 
2

Chia sẻ sourceDirectories như trong câu trả lời làm lập tức là cách đơn giản nhất để đi về nó, nhưng tiếc là nó sẽ không làm việc tốt với IntelliJ vì mô hình dự án không cho phép rễ nguồn chia sẻ giữa nhiều mô-đun.

Phương pháp của Seth Tisue sẽ hoạt động, nhưng yêu cầu xây dựng lại để cập nhật nguồn.

Để chia sẻ các nguồn thực sự và nhờ IntelliJ trực tiếp nhận nguồn, bạn có thể xác định mô-đun trong bản dựng.

Phương pháp sau đây dường như chỉ có tác dụng trong SBT 1.0 trở lên

Tạo một file project/metabuild.sbt:

val buildShared = project 
val buildRoot = (project in file(".")) 
    .dependsOn(buildShared) 

và bạn build.sbt:

val buildShared = ProjectRef(file("project"), "buildShared") 
val root = (project in file(".")) 
    .dependsOn(buildShared) 

Sau đó đặt mã chia sẻ của bạn trong project/buildShared/src/main/scala/ và làm mới.dự án của bạn sẽ trông giống như thế này trong IntelliJ:

enter image description here

Full dụ dự án: https://github.com/jastice/shared-build-sources

+1

Câu trả lời hay, nhưng trong dự án liên kết của bạn, thư mục dự án dường như bị thiếu? –

+0

cảm ơn, đã được chỉnh sửa ngay bây giờ! –

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