Aku keluar dari lemari ini! Saya tidak mengerti SBT. Di sana, saya mengatakannya, sekarang tolong bantu saya.
Semua jalan menuju Roma, dan itu adalah sama untuk SBT: Untuk memulai SBT
ada SBT
, SBT Launcher
, SBT-extras
, dll, dan kemudian ada berbagai cara untuk memasukkan dan memutuskan repositori. Apakah ada cara 'terbaik'?
Saya bertanya karena terkadang saya sedikit tersesat. Dokumentasi SBT sangat lengkap dan menyeluruh, tetapi saya tidak tahu kapan harus menggunakan build.sbt
atau project/build.properties
atau project/Build.scala
atau project/plugins.sbt
.
Kemudian menjadi menyenangkan, ada Scala-IDE
dan SBT
- Apa cara yang benar untuk menggunakannya bersama? Apa yang lebih dulu, ayam atau telur?
Yang paling penting mungkin, bagaimana Anda menemukan repositori dan versi yang tepat untuk disertakan dalam proyek Anda? Apakah saya baru saja mengeluarkan parang dan mulai meretas jalan ke depan? Saya cukup sering menemukan proyek yang mencakup semuanya dan wastafel dapur, dan kemudian saya menyadari - saya bukan satu-satunya yang sedikit tersesat.
Sebagai contoh sederhana, saat ini, saya sedang memulai proyek baru. Saya ingin menggunakan fitur terbaru dari SLICK
dan Scala
dan ini mungkin memerlukan SBT versi terbaru. Apa hal yang waras untuk memulai, dan mengapa? Dalam file apa saya harus mendefinisikannya dan bagaimana tampilannya? Saya tahu saya bisa mendapatkan ini berfungsi, tetapi saya benar-benar ingin pendapat ahli tentang ke mana semuanya harus pergi (mengapa harus pergi akan ada bonus).
Saya telah menggunakan SBT
untuk proyek kecil selama lebih dari setahun sekarang. Saya menggunakan SBT
dan kemudian SBT Extras
(karena itu membuat beberapa sakit kepala hilang secara ajaib), tetapi saya tidak yakin mengapa saya harus menggunakan yang satu atau yang lain. Saya hanya merasa sedikit frustrasi karena tidak memahami bagaimana segala sesuatunya cocok ( SBT
dan repositori), dan berpikir itu akan menyelamatkan orang yang datang dengan cara ini dari banyak kesulitan jika hal ini dapat dijelaskan dalam istilah manusia.
Build.scala
untuk menyiapkan classpath, dan itulah mengapa Anda benar-benar membutuhkan sbteclipse untuk menghasilkan Eclipse .classpath. Semoga ini membantu.Jawaban:
Untuk dependensi berbasis Scala, saya akan mengikuti apa yang penulis rekomendasikan. Misalnya: http://code.google.com/p/scalaz/#SBT menunjukkan untuk menggunakan:
Atau https://github.com/typesafehub/sbteclipse/ memiliki instruksi tentang tempat untuk menambahkan:
Untuk dependensi berbasis Java, saya menggunakan http://mvnrepository.com/ untuk melihat apa yang ada di luar sana, lalu klik pada tab SBT. Misalnya http://mvnrepository.com/artifact/net.sf.opencsv/opencsv/2.3 menunjukkan untuk menggunakan:
Kemudian tarik keluar parang dan mulailah meretas jalan ke depan. Jika Anda beruntung, Anda tidak akan menggunakan toples yang bergantung pada beberapa toples yang sama tetapi dengan versi yang tidak kompatibel. Mengingat ekosistem Java, Anda sering kali berakhir dengan memasukkan semuanya dan wastafel dapur dan perlu beberapa upaya untuk menghilangkan ketergantungan atau memastikan Anda tidak melewatkan ketergantungan yang diperlukan.
Saya pikir hal yang waras adalah membangun kekebalan sbt secara bertahap .
Pastikan Anda mengerti:
{<build-uri>}<project-id>/config:key(for task-key)
SettingKey
,TaskKey
,InputKey
) - baca bagian yang disebut "Task Keys" di http://www.scala-sbt.org/release/docs/Getting-Started/Basic-DefBiarkan 4 halaman itu terbuka setiap saat sehingga Anda dapat melompat dan mencari berbagai definisi dan contoh:
Manfaatkan
show
daninspect
dan penyelesaian tab secara maksimal untuk membiasakan diri dengan nilai sebenarnya dari pengaturan, ketergantungannya, definisi dan pengaturan terkait. Saya tidak percaya hubungan yang akan Anda temukan menggunakaninspect
didokumentasikan di mana pun. Jika ada cara yang lebih baik saya ingin mengetahuinya.sumber
Cara saya menggunakan sbt adalah:
project
folder denganMyProject.scala
file untuk menyiapkan sbt. Saya lebih suka ini daripadabuild.sbt
pendekatan - ini scala dan lebih fleksibelproject/plugins.sbt
file dan tambahkan plugin yang sesuai untuk IDE Anda. Baik sbt-eclipse, sbt-idea atau ensime-sbt-cmd sehingga Anda dapat menghasilkan file proyek untuk eclipse, intellij atau ensime.Saya tidak repot-repot memeriksa file proyek IDE karena dibuat oleh sbt, tetapi mungkin ada alasan Anda ingin melakukannya.
Anda dapat melihat contoh penyiapan seperti ini di sini .
sumber
Gunakan Typeafe Activator, cara mewah untuk memanggil sbt, yang dilengkapi dengan template dan seed proyek: https://typesafe.com/activator
sumber
Instalasi
brew install sbt
atau instalasi serupa sbt yang secara teknis terdiri dariKetika Anda mengeksekusi
sbt
dari terminal, itu benar-benar menjalankan skrip sbt launcher bash. Secara pribadi, saya tidak perlu khawatir tentang trinitas ini, dan hanya menggunakan sbt seolah-olah itu adalah satu hal.Konfigurasi
Untuk mengkonfigurasi sbt untuk proyek tertentu, simpan
.sbtopts
file di root proyek. Untuk mengkonfigurasi modifikasi sbt di seluruh sistem/usr/local/etc/sbtopts
. Pelaksanasbt -help
harus memberi tahu Anda lokasi yang tepat. Misalnya, untuk memberikan sbt lebih banyak memori saat satu kali dijalankansbt -mem 4096
, atau simpan-mem 4096
dalam.sbtopts
atausbtopts
agar peningkatan memori berlaku secara permanen.Struktur proyek
sbt new scala/scala-seed.g8
membuat struktur proyek Hello World sbt minimalPerintah yang sering
Segudang cangkang
Definisi build adalah proyek Scala yang tepat
Ini adalah salah satu konsep kunci idiomatik sbt. Saya akan mencoba menjelaskan dengan sebuah pertanyaan. Katakanlah Anda ingin mendefinisikan tugas sbt yang akan menjalankan permintaan HTTP dengan scalaj-http. Secara intuitif kita mungkin mencoba yang berikut di dalam
build.sbt
Namun ini akan kesalahan mengatakan hilang
import scalaj.http._
. Bagaimana ini mungkin ketika kita, tepat di atas, ditambahkanscalaj-http
kelibraryDependencies
? Lebih jauh, mengapa ini berfungsi ketika, sebagai gantinya, kita menambahkan ketergantungan keproject/build.sbt
?Jawabannya adalah itu
fooTask
sebenarnya adalah bagian dari proyek Scala yang terpisah dari proyek utama Anda. Proyek Scala yang berbeda ini dapat ditemukan di bawahproject/
direktori yang memilikitarget/
direktori sendiri tempat kelas yang dikompilasinya berada. Sebenarnya, di bawahproject/target/config-classes
harus ada kelas yang mendekompilasi menjadi sepertiKami melihat itu
fooTask
hanyalah anggota dari objek Scala biasa bernama$9c2192aea3f1db3c251d
. Jelasscalaj-http
harus menjadi ketergantungan proyek yang mendefinisikan$9c2192aea3f1db3c251d
dan bukan ketergantungan proyek yang tepat. Oleh karena itu perlu dideklarasikanproject/build.sbt
sebagai penggantibuild.sbt
, karena diproject
situlah definisi build proyek Scala berada.Untuk menunjukkan bahwa definisi build hanyalah proyek Scala lainnya, jalankan
sbt consoleProject
. Ini akan memuat Scala REPL dengan proyek definisi build di classpath. Anda akan melihat impor di sepanjang barisJadi sekarang kita dapat berinteraksi langsung dengan proyek definisi pembangunan dengan memanggilnya dengan Scala proper, bukan
build.sbt
DSL. Misalnya, eksekusi berikut inifooTask
build.sbt
under root project adalah DSL khusus yang membantu menentukan definisi build proyek Scala di bawahproject/
.Dan membangun definisi proyek Scala, dapat memiliki proyek Scala definisi membangun sendiri di bawah
project/project/
dan seterusnya. Kami mengatakan sbt bersifat rekursif .sbt sejajar secara default
sbt membangun DAG dari tugas. Ini memungkinkannya untuk menganalisis ketergantungan antara tugas dan menjalankannya secara paralel dan bahkan melakukan deduplikasi.
build.sbt
DSL dirancang dengan pemikiran ini, yang mungkin mengarah pada semantik awalnya yang mengejutkan. Menurut Anda, bagaimana urutan eksekusi dalam cuplikan berikut?Secara intuitif orang mungkin berpikir aliran di sini adalah mencetak terlebih dahulu
hello
kemudian mengeksekusia
, dan kemudianb
tugas. Namun hal ini sebenarnya berarti mengeksekusia
danb
di paralel , dan sebelumprintln("hello")
jadiatau karena urutan
a
danb
tidak dijaminMungkin secara paradoks, di sbt lebih mudah melakukan paralel daripada serial. Jika Anda memerlukan pengurutan serial, Anda harus menggunakan hal-hal khusus seperti
Def.sequential
atauDef.taskDyn
untuk meniru pemahaman .mirip dengan
di mana kami melihat tidak ada ketergantungan antar komponen, sementara
mirip dengan
di mana kita melihat
sum
tergantung dan harus menunggua
danb
.Dengan kata lain
.value
sequential
atautaskDyn
Pertimbangkan cuplikan lain yang secara semantik membingungkan sebagai akibat dari sifat membangun ketergantungan
value
, where, dan bukannyakita harus menulis
Perhatikan bahwa sintaks
.value
adalah tentang hubungan di DAG dan tidak berartisebaliknya itu berarti sesuatu seperti
Jadi sekarang mungkin sedikit lebih jelas mengapa
x
belum bisa diberi nilai; belum ada nilai yang tersedia dalam tahap membangun hubungan.Kami dapat dengan jelas melihat perbedaan dalam semantik antara Scala proper dan bahasa DSL di
build.sbt
. Berikut adalah beberapa aturan praktis yang cocok untuk sayaSetting[T]
.value
sintaks dan sbt akan menjaga hubungan antaraSetting[T]
Def.sequential
atauDef.taskDyn
Perintah vs Tugas
Perintah adalah jalan keluar malas dari DAG. Dengan menggunakan perintah, mudah untuk mengubah status build dan membuat serial tugas sesuai keinginan. Kerugiannya adalah kita kehilangan kesejajaran dan deduplikasi tugas yang disediakan oleh DAG, yang mana tugas harus menjadi pilihan yang lebih disukai. Anda dapat menganggap perintah sebagai semacam rekaman permanen dari sesi yang mungkin dilakukan di dalam
sbt shell
. Misalnya, diberikanpertimbangkan hasil dari sesi berikutnya
Secara khusus, bukan cara kami mengubah status build dengan
set x := 41
. Perintah memungkinkan kita membuat rekaman permanen dari sesi di atas, misalnyaKita juga bisa membuat perintah type-safe menggunakan
Project.extract
danrunTask
Cakupan
Cakupan mulai berperan saat kami mencoba menjawab jenis pertanyaan berikut
sbt memiliki ruang lingkup multi-sumbu yang dapat dinavigasi menggunakan sintaks garis miring , misalnya,
Secara pribadi, saya jarang merasa khawatir tentang ruang lingkup. Terkadang saya hanya ingin mengumpulkan sumber pengujian
atau mungkin menjalankan tugas tertentu dari subproyek tertentu tanpa harus menavigasi ke proyek itu terlebih dahulu dengan
project subprojB
Saya pikir aturan praktis berikut membantu menghindari komplikasi pelingkupan
build.sbt
file tetapi hanya satu file master di bawah proyek root yang mengontrol semua subproyek lainnyaval
dan secara eksplisit menambahkannya ke setiap sub-proyekPembangunan multi-proyek
Alih-alih beberapa file build.sbt untuk setiap subproyek
Miliki satu master
build.sbt
untuk mengatur semuanyaAda praktik umum dalam memfaktorkan setelan umum dalam build multi-project
sebagai contoh
Proyek navigasi
Plugin
Ingat definisi build adalah proyek Scala yang tepat yang berada di bawah
project/
. Di sinilah kami mendefinisikan plugin dengan membuat.scala
fileBerikut adalah plugin otomatis minimal di bawah
project/FooPlugin.scala
Timpa
harus efektif mengaktifkan plugin untuk semua sub-proyek tanpa harus memanggil secara eksplisit
enablePlugin
dalambuild.sbt
.IntelliJ dan sbt
Harap aktifkan pengaturan berikut (yang seharusnya diaktifkan secara default )
dibawah
Referensi kunci
sumber