Estou saindo do armário por causa disso! Não entendo SBT. Pronto, eu disse, agora me ajude por favor.
Todos os caminhos levam a Roma, e que é o mesmo para SBT: Para começar com o SBT
que há SBT
, SBT Launcher
, SBT-extras
, etc, e, em seguida, há diferentes maneiras de incluir e decidir sobre repositórios. Existe uma 'melhor' maneira?
Estou perguntando porque às vezes fico um pouco perdida. A documentação do SBT é muito minuciosa e completa, mas não sei quando usar build.sbt
ou project/build.properties
ou project/Build.scala
ou project/plugins.sbt
.
Aí fica divertido, tem o Scala-IDE
e SBT
- Qual é a maneira correta de usá-los juntos? O que vem primeiro, a galinha ou o ovo?
O mais importante é provavelmente, como você encontra os repositórios e versões corretas para incluir em seu projeto?Eu simplesmente puxo uma machete e começo a abrir caminho para frente? Muitas vezes encontro projetos que incluem tudo e a pia da cozinha, e então eu percebo - eu não sou o único que fica um pouco perdido.
Como um exemplo simples, agora estou começando um novo projeto. Desejo usar os recursos mais recentes do SLICK
e Scala
provavelmente exigirá a versão mais recente do SBT. Qual é o ponto lógico para começar e por quê?Em que arquivo devo defini-lo e como deve aparecer? Eu sei que posso fazer isso funcionar, mas eu realmente gostaria de uma opinião de um especialista sobre onde tudo deve ir (por que deveria ir, será um bônus).
Eu tenho usado SBT
para pequenos projetos por mais de um ano. Usei SBT
e então SBT Extras
(pois fazia algumas dores de cabeça desaparecerem magicamente), mas não tenho certeza por que deveria usar um ou outro. Estou apenas ficando um pouco frustrado por não entender como as coisas se encaixam ( SBT
e os repositórios), e acho que isso salvará o próximo cara que vier para cá de muitas dificuldades se isso puder ser explicado em termos humanos.
Build.scala
para configurar o classpath, e é por isso que você realmente precisa do sbteclipse para gerar o Eclipse .classpath. Espero que isto ajude.Respostas:
Para dependências baseadas em Scala, eu seguiria o que os autores recomendam. Por exemplo: http://code.google.com/p/scalaz/#SBT indica para usar:
Ou https://github.com/typesafehub/sbteclipse/ tem instruções sobre onde adicionar:
Para dependências baseadas em Java, eu uso http://mvnrepository.com/ para ver o que está disponível e, a seguir, clico na guia SBT. Por exemplo http://mvnrepository.com/artifact/net.sf.opencsv/opencsv/2.3 indica para usar:
Em seguida, retire a machete e comece a abrir caminho para a frente. Se você tiver sorte, não acabará usando potes que dependem de alguns dos mesmos potes, mas com versões incompatíveis. Dado o ecossistema Java, muitas vezes você acaba incluindo tudo e a pia da cozinha e é preciso algum esforço para eliminar as dependências ou garantir que você não perca as dependências necessárias.
Acho que o ponto mais lógico é construir imunidade ao sbt gradualmente .
Certifique-se de entender:
{<build-uri>}<project-id>/config:key(for task-key)
SettingKey
,TaskKey
,InputKey
) - leia a seção chamada "Tarefa Keys" em http://www.scala-sbt.org/release/docs/Getting-Started/Basic-DefMantenha essas 4 páginas abertas o tempo todo para que você possa pular e procurar várias definições e exemplos:
Fazer uso máximo de
show
einspect
e a conclusão guia para se familiarizar com os valores reais de configurações, suas dependências, definições e configurações relacionadas. Não acredito que os relacionamentos que você descobrirá usandoinspect
estejam documentados em qualquer lugar. Se existe uma maneira melhor, eu quero saber sobre isso.fonte
A forma como eu uso sbt é:
project
pasta com umMyProject.scala
arquivo para configurar o sbt. Eu prefiro muito mais isso dobuild.sbt
que a abordagem - é uma escala e é mais flexívelproject/plugins.sbt
arquivo e adicione o plugin apropriado para o seu IDE. Tanto sbt-eclipse, sbt-idea ou ensime-sbt-cmd para que você possa gerar arquivos de projeto para eclipse, intellij ou ensime.Não me incomodo em verificar os arquivos do projeto IDE, pois eles são gerados pelo sbt, mas pode haver motivos para você querer fazer isso.
Você pode ver um exemplo configurado como este aqui .
fonte
Use o Typesafe Activator, uma maneira sofisticada de chamar sbt, que vem com modelos e sementes de projeto: https://typesafe.com/activator
fonte
Instalação
brew install sbt
ou instalações semelhantes sbt que, tecnicamente falando, consistem emQuando você executa
sbt
do terminal, ele realmente executa o script bash do iniciador sbt. Pessoalmente, nunca tive que me preocupar com essa trindade, e apenas usar sbt como se fosse uma única coisa.Configuração
Para configurar o sbt para um determinado projeto, salve o
.sbtopts
arquivo na raiz do projeto. Para configurar a modificação de todo o sistema sbt/usr/local/etc/sbtopts
. A execuçãosbt -help
deve informar a localização exata. Por exemplo, para dar ao sbt mais memória como execução únicasbt -mem 4096
, ou salvar-mem 4096
em.sbtopts
ousbtopts
para que o aumento da memória tenha efeito permanente.Estrutura do projeto
sbt new scala/scala-seed.g8
cria uma estrutura de projeto sbt Hello World mínimaComandos frequentes
Miríade de conchas
A definição de construção é um projeto Scala adequado
Este é um dos principais conceitos idiomáticos de sbt. Vou tentar explicar com uma pergunta. Digamos que você queira definir uma tarefa sbt que executará uma solicitação HTTP com scalaj-http. Intuitivamente, podemos tentar o seguinte dentro
build.sbt
No entanto, ocorrerá um erro dizendo ausente
import scalaj.http._
. Como isso é possível quando, logo acima, adicionadoscalaj-http
alibraryDependencies
? Além disso, por que funciona quando, em vez disso, adicionamos a dependência aproject/build.sbt
?A resposta é que,
fooTask
na verdade, é parte de um projeto Scala separado do seu projeto principal. Este projeto Scala diferente pode ser encontrado em umproject/
diretório que possui seu própriotarget/
diretório onde residem suas classes compiladas. Na verdade, abaixoproject/target/config-classes
deve haver uma classe que descompila para algo comoVemos que
fooTask
é simplesmente um membro de um objeto Scala normal chamado$9c2192aea3f1db3c251d
. Claramentescalaj-http
deve ser uma dependência da definição do projeto$9c2192aea3f1db3c251d
e não a dependência do projeto adequado. Portanto, ele precisa ser declarado em emproject/build.sbt
vez debuild.sbt
, porqueproject
é onde reside o projeto Scala de definição de construção.Para conduzir ao ponto de que a definição de construção é apenas outro projeto Scala, execute
sbt consoleProject
. Isso carregará o Scala REPL com o projeto de definição de construção no classpath. Você deve ver uma importação ao longo das linhas dePortanto, agora podemos interagir diretamente com o projeto de definição de construção, chamando-o com Scala adequado em vez de
build.sbt
DSL. Por exemplo, o seguinte executafooTask
build.sbt
under root project é uma DSL especial que ajuda a definir a definição de build do projeto Scala emproject/
.E o projeto Scala de definição de construção, pode ter seu próprio projeto Scala de definição de construção em
project/project/
e assim por diante. Dizemos que sbt é recursivo .sbt é paralelo por padrão
sbt cria DAG fora de tarefas. Isso permite analisar dependências entre tarefas e executá-las em paralelo e até mesmo realizar a desduplicação.
build.sbt
O DSL foi projetado com isso em mente, o que pode levar a uma semântica inicialmente surpreendente. Qual você acha que é a ordem de execução no trecho a seguir?Intuitivamente, pode-se pensar que o fluxo aqui é primeiro imprimir,
hello
depois executara
e, em seguida, realizar ab
tarefa. No entanto, isso realmente significa executara
eb
em paralelo , e antesprintln("hello")
dissoou porque a ordem de
a
eb
não é garantidaTalvez paradoxalmente, em sbt seja mais fácil fazer paralelo do que serial. Se você precisar de pedido em série, terá que usar coisas especiais como
Def.sequential
ouDef.taskDyn
para emular para compreensão .é similar a
onde vemos que não há dependências entre os componentes, embora
é similar a
onde vemos
sum
depende e tem que esperara
eb
.Em outras palavras
.value
sequential
outaskDyn
Considere outro snippet semanticamente confuso como resultado da natureza de construção de dependência de
value
, onde em vez detemos que escrever
Observe que a sintaxe
.value
é sobre relacionamentos no DAG e não significaem vez disso, significa algo como
Portanto, agora pode ficar um pouco mais claro por
x
que não pode ser atribuído um valor ainda; ainda não há valor disponível na fase de construção de relacionamento.Podemos ver claramente uma diferença na semântica entre Scala e a linguagem DSL em
build.sbt
. Aqui estão algumas regras de polegar que funcionam para mimSetting[T]
.value
sintaxe e sbt cuidará de estabelecer a relação entreSetting[T]
Def.sequential
ouDef.taskDyn
Comandos vs Tarefas
Os comandos são uma forma preguiçosa de sair do DAG. Usando comandos, é fácil alterar o estado de compilação e serializar tarefas como desejar. O custo é que perdemos a paralelização e a desduplicação das tarefas fornecidas pelo DAG, de forma que as tarefas devem ser a escolha preferida. Você pode pensar nos comandos como uma espécie de gravação permanente de uma sessão que pode ser feita internamente
sbt shell
. Por exemplo, dadoconsidere o resultado da sessão seguinte
Em particular, não como alteramos o estado de construção com
set x := 41
. Os comandos nos permitem fazer uma gravação permanente da sessão acima, por exemploTambém podemos tornar o tipo de comando seguro usando
Project.extract
erunTask
Scopes
Os escopos entram em ação quando tentamos responder aos seguintes tipos de perguntas
sbt tem um espaço de escopo multi-eixo que pode ser navegado usando sintaxe de barra , por exemplo,
Pessoalmente, raramente me vejo tendo que me preocupar com o escopo. Às vezes eu quero compilar apenas fontes de teste
ou talvez execute uma tarefa específica de um subprojeto específico sem primeiro ter que navegar para esse projeto com
project subprojB
Acho que as seguintes regras ajudam a evitar complicações de escopo
build.sbt
arquivos, mas apenas um único mestre no projeto raiz que controla todos os outros subprojetosval
e adicioná-las explicitamente a cada subprojetoCompilação de vários projetos
Em vez de vários arquivos build.sbt para cada subprojeto
Tenha um único mestre
build.sbt
para governar todos elesHá uma prática comum de fatorar configurações comuns em compilações de vários projetos
por exemplo
Navegação de projetos
Plugins
Lembre-se de que a definição de construção é um projeto Scala adequado que reside em
project/
. É aqui que definimos um plugin criando.scala
arquivosAqui está um plugin automático mínimo em
project/FooPlugin.scala
A substituição
deve habilitar efetivamente o plugin para todos os subprojetos sem ter que chamar explicitamente
enablePlugin
embuild.sbt
.IntelliJ e sbt
Habilite a seguinte configuração (que deve ser habilitada por padrão )
debaixo
Referências chave
fonte