Wychodzę z szafy w tej sprawie! Nie rozumiem SBT. Tam, powiedziałem to, teraz pomóż mi, proszę.
Wszystkie drogi prowadzą do Rzymu, a to jest taki sam dla SBT: Aby zacząć SBT
tam jest SBT
, SBT Launcher
, SBT-extras
itp, a następnie istnieją różne sposoby obejmują i zdecydować się na repozytoriach. Czy istnieje „najlepszy” sposób?
Pytam, bo czasem się trochę gubię. Dokumentacja SBT jest bardzo dokładna i kompletna, ale nie wiem, kiedy użyć build.sbt
lub project/build.properties
lub project/Build.scala
lub project/plugins.sbt
.
Wtedy staje się zabawne, jest Scala-IDE
i SBT
- Jaki jest prawidłowy sposób ich wspólnego używania? Co jest pierwsze, kura czy jajko?
Najważniejsze jest prawdopodobnie, jak znaleźć odpowiednie repozytoria i wersje, które chcesz uwzględnić w swoim projekcie? Czy po prostu wyciągam maczetę i zaczynam się przedzierać? Dość często znajduję projekty, które zawierają wszystko i zlewozmywak i wtedy zdaję sobie sprawę - nie tylko ja się trochę gubię.
Jako prosty przykład, zaczynam teraz zupełnie nowy projekt. Chcę korzystać z najnowszych funkcji SLICK
i Scala
i to prawdopodobnie wymagać będzie ostatnią wersję SBT. Jaki jest rozsądny punkt na początek i dlaczego? W jakim pliku mam to zdefiniować i jak powinien wyglądać? Wiem, że mogę to uruchomić, ale naprawdę chciałbym uzyskać opinię eksperta na temat tego, gdzie wszystko powinno się udać (dlaczego powinno iść, będzie premia).
Używam SBT
do małych projektów od ponad roku. Użyłem, SBT
a potem SBT Extras
(ponieważ spowodowało to magiczne zniknięcie niektórych bólów głowy), ale nie jestem pewien, dlaczego powinienem używać jednego lub drugiego. Jestem trochę sfrustrowany, że nie rozumiem, jak rzeczy do siebie pasują ( SBT
i repozytoria) i myślę, że zaoszczędzi to następnemu facetowi, który przychodzi w ten sposób, wiele trudności, jeśli można to wyjaśnić w kategoriach ludzkich.
Build.scala
ścieżki klas i dlatego tak naprawdę potrzebujesz sbteclipse, aby wygenerować Eclipse .classpath. Mam nadzieję że to pomoże.Odpowiedzi:
W przypadku zależności opartych na Scali postąpiłbym zgodnie z zaleceniami autorów. Na przykład: http://code.google.com/p/scalaz/#SBT wskazuje na użycie:
Lub https://github.com/typesafehub/sbteclipse/ zawiera instrukcje, gdzie dodać:
W przypadku zależności opartych na Javie używam http://mvnrepository.com/, aby zobaczyć, co tam jest, a następnie klikam kartę SBT. Na przykład http://mvnrepository.com/artifact/net.sf.opencsv/opencsv/2.3 wskazuje na użycie:
Następnie wyciągnij maczetę i zacznij siekać przed siebie. Jeśli masz szczęście, nie będziesz używać słoików, które zależą od niektórych z tych samych słoików, ale z niekompatybilnymi wersjami. Biorąc pod uwagę ekosystem Java, często kończy się to na dołączeniu wszystkiego i zlewu kuchennego, a wyeliminowanie zależności lub zapewnienie, że nie brakuje wymaganych zależności, wymaga pewnego wysiłku.
Myślę, że rozsądnym punktem jest stopniowe budowanie odporności na kogoś .
Upewnij się, że rozumiesz:
{<build-uri>}<project-id>/config:key(for task-key)
SettingKey
,TaskKey
,InputKey
) - przeczytaj rozdział o nazwie „Keys zadania” w http://www.scala-sbt.org/release/docs/Getting-Started/Basic-DefMiej te 4 strony otwarte przez cały czas, abyś mógł przeskoczyć i wyszukać różne definicje i przykłady:
Maksymalnie wykorzystaj
show
iinspect
oraz uzupełnianie kart, aby zapoznać się z rzeczywistymi wartościami ustawień, ich zależnościami, definicjami i powiązanymi ustawieniami. Nie wierzę, że relacje, które odkryjesz,inspect
są gdziekolwiek udokumentowane. Jeśli istnieje lepszy sposób, chcę się o tym dowiedzieć.źródło
Sposób, w jaki używam sbt, to:
project
folder zMyProject.scala
plikiem do konfiguracji sbt. O wiele wolę to odbuild.sbt
podejścia - jest skala i jest bardziej elastyczneproject/plugins.sbt
plik i dodaj odpowiednią wtyczkę do swojego IDE. Albo sbt-eclipse, sbt-idea lub ensime-sbt-cmd, aby można było generować pliki projektów dla eclipse, intellij lub ensime.Nie zawracam sobie głowy sprawdzaniem plików projektu IDE, ponieważ są one generowane przez sbt, ale mogą być powody, dla których chcesz to zrobić.
Możesz zobaczyć przykład skonfigurowany w ten sposób tutaj .
źródło
Użyj Aktywatora Typesafe, fantazyjnego sposobu dzwonienia do sbt, który jest dostarczany z szablonami projektów i nasionami: https://typesafe.com/activator
źródło
Instalacja
brew install sbt
lub podobne instalacje, z których technicznie rzecz biorąc składa sięKiedy wykonujesz
sbt
z terminala, faktycznie uruchamia skrypt bash programu uruchamiającego SBT. Osobiście nigdy nie musiałem martwić się o tę trójcę i po prostu używać sbt tak, jakby to była jedna rzecz.Konfiguracja
Aby skonfigurować sbt dla określonego
.sbtopts
pliku zapisu projektu w katalogu głównym projektu. Aby skonfigurować sbt w całym systemie, modyfikuj/usr/local/etc/sbtopts
. Wykonaniesbt -help
powinno podać dokładną lokalizację. Na przykład, aby dać sbt więcej pamięci jako jednorazowe wykonaniesbt -mem 4096
lub zapisać-mem 4096
w.sbtopts
lub wsbtopts
celu zwiększenia pamięci, aby zadziałało na stałe.Struktura projektu
sbt new scala/scala-seed.g8
tworzy minimalną strukturę projektu Hello World SBTCzęste polecenia
Niezliczone muszle
Definicja kompilacji to właściwy projekt Scala
To jedna z kluczowych idiomatycznych koncepcji sbt. Spróbuję wyjaśnić pytaniem. Powiedzmy, że chcesz zdefiniować zadanie SBT, które wykona żądanie HTTP za pomocą scalaj-http. Intuicyjnie możemy wypróbować następujące rozwiązania
build.sbt
Jednak będzie to błąd z informacją o braku
import scalaj.http._
. Jak to możliwe, kiedy, tuż powyżej, dodajescalaj-http
sięlibraryDependencies
? Co więcej, dlaczego to działa, skoro zamiast tego dodajemy zależność doproject/build.sbt
?Odpowiedź jest taka, że w
fooTask
rzeczywistości jest to część oddzielnego projektu Scala od twojego głównego projektu. Ten inny projekt Scala można znaleźć wproject/
katalogu, który ma własnytarget/
katalog, w którym znajdują się jego skompilowane klasy. W rzeczywistości podproject/target/config-classes
powinna znajdować się klasa, która dekompiluje się do czegoś podobnegoWidzimy, że
fooTask
jest to po prostu członek zwykłego obiektu Scala o nazwie$9c2192aea3f1db3c251d
. Oczywiściescalaj-http
powinna to być zależność projektu definiującego,$9c2192aea3f1db3c251d
a nie zależność odpowiedniego projektu. Dlatego należy go zadeklarować wproject/build.sbt
zamiastbuild.sbt
, ponieważproject
jest to miejsce, w którym znajduje się definicja kompilacji projekt Scala.Aby wskazać, że definicja kompilacji to tylko kolejny projekt Scali, wykonaj
sbt consoleProject
. Spowoduje to załadowanie Scala REPL z projektem definicji kompilacji w ścieżce klas. Powinieneś zobaczyć import wzdłuż liniiWięc teraz możemy bezpośrednio współdziałać z projektem definicji kompilacji, wywołując go za pomocą właściwej Scali zamiast
build.sbt
DSL. Na przykład wykonuje następujące czynnościfooTask
build.sbt
w ramach projektu głównego jest specjalnym DSL, który pomaga zdefiniować definicję kompilacji projektu Scala w ramachproject/
.Definicja kompilacji Projekt Scala może mieć własną definicję kompilacji Projekt Scala
project/project/
i tak dalej. Mówimy, że sbt jest rekurencyjny .sbt jest domyślnie równoległy
sbt buduje DAG z zadań. Pozwala to analizować zależności między zadaniami i wykonywać je równolegle, a nawet przeprowadzać deduplikację.
build.sbt
DSL został zaprojektowany z myślą o tym, co może prowadzić do początkowo zaskakującej semantyki. Jak myślisz, jaka jest kolejność wykonywania w poniższym fragmencie?Intuicyjnie można by pomyśleć płynąć tutaj jest do pierwszego wydruku
hello
potem wykonaniea
, a następnieb
zadania. Jednak w rzeczywistości oznacza to wykonaća
ib
w równolegle , a przedprintln("hello")
taklub ponieważ kolejność
a
ib
nie jest gwarantowanaByć może paradoksalnie, w sbt łatwiej jest robić równolegle niż szeregowo. Jeśli potrzebujesz zamówień seryjnych, będziesz musiał użyć specjalnych rzeczy, takich jak
Def.sequential
lubDef.taskDyn
do naśladowania zrozumienia .jest podobne do
gdzie widzimy, że nie ma zależności między komponentami, podczas gdy
jest podobne do
to, gdzie widzimy,
sum
zależy od i musi czekać naa
ib
.Innymi słowy
.value
sequential
lubtaskDyn
Rozważ inny semantycznie mylący fragment kodu w wyniku natury budowania zależności
value
, gdzie zamiastmusimy pisać
Zwróć uwagę, że składnia
.value
dotyczy relacji w DAG i nie oznaczazamiast tego oznacza coś takiego
Więc teraz może być trochę jaśniejsze, dlaczego
x
nie można jeszcze przypisać wartości; nie ma jeszcze wartości na etapie budowania relacji.Wyraźnie widać różnicę w semantyce między właściwą Scalą a językiem DSL w
build.sbt
. Oto kilka praktycznych zasad, które sprawdzają się w moim przypadkuSetting[T]
.value
składni, a sbt zajmie się ustanowieniem relacji międzySetting[T]
Def.sequential
lubDef.taskDyn
Polecenia a zadania
Polecenia są leniwym wyjściem z DAG. Za pomocą poleceń można łatwo modyfikować stan kompilacji i serializować zadania zgodnie z potrzebami. Kosztem jest to, że tracimy zrównoleglanie i deduplikację zadań dostarczanych przez DAG, którą drogą zadania powinny być preferowane. Możesz myśleć o poleceniach jako o rodzaju trwałego nagrania sesji, którą można wykonać w środku
sbt shell
. Na przykład podanerozważ wyniki następnej sesji
W szczególności nie dotyczy to sposobu zmiany stanu kompilacji za pomocą
set x := 41
. Polecenia pozwalają np. Na trwałe nagranie powyższej sesjiMożemy również uczynić polecenie bezpiecznym, używając
Project.extract
irunTask
Zakresy
Lunety wchodzą w grę, gdy próbujemy odpowiedzieć na następujące rodzaje pytań
sbt ma wieloosiową przestrzeń zakresu, po której można nawigować za pomocą składni ukośnika , na przykład
Osobiście rzadko muszę się martwić o zakres. Czasami chcę skompilować tylko źródła testowe
a może wykonać określone zadanie z określonego podprojektu bez konieczności wcześniejszego przechodzenia do tego projektu za pomocą
project subprojB
Myślę, że poniższe praktyczne zasady pomogą uniknąć komplikacji związanych z określaniem zakresu
build.sbt
plików, ale tylko jeden główny w projekcie głównym, który kontroluje wszystkie inne podprojektyval
i dodaj je do każdego podprojektuKompilacja wieloprojektowa
Zamiast wielu plików build.sbt dla każdego podprojektu
Miej jednego pana,
build.sbt
który będzie rządził wszystkimiIstnieje powszechna praktyka uwzględniania wspólnych ustawień w kompilacjach obejmujących wiele projektów
na przykład
Nawigacja projektów
Wtyczki
Pamiętaj, że definicja kompilacji to właściwy projekt Scala, który znajduje się w
project/
. W tym miejscu definiujemy wtyczkę, tworząc.scala
plikiOto minimalne auto plugin pod
project/FooPlugin.scala
Zastąpienie
powinny skutecznie włączyć wtyczkę dla wszystkich podprojektów bez konieczności wzywania wyraźnie
enablePlugin
wbuild.sbt
.IntelliJ i sbt
Włącz następujące ustawienie (które powinno być domyślnie włączone )
pod
Kluczowe odniesienia
źródło