Introdução ao monorepositório com Kotlin
O desenvolvimento moderno de aplicações complexas frequentemente enfrenta o problema de gerenciamento de código. A escolha entre monorepositório e multirrepositório é uma das decisões arquiteturais chave. Neste artigo, vamos analisar como organizar um monorepositório com Kotlin, usando as melhores práticas e ferramentas modernas.
Monorepositório (monorepo) é uma abordagem onde todos os projetos, bibliotecas e serviços são armazenados em um único repositório. Para desenvolvedores Kotlin, isso é especialmente relevante devido ao poderoso sistema de build Gradle e à possibilidade de usar código compartilhado entre diferentes módulos.
Vantagens do monorepositório para projetos Kotlin
Antes de passar à organização, vamos considerar as principais vantagens do monorepositório para Kotlin:
- Versão única de dependências — todos os módulos usam a mesma versão de Kotlin, bibliotecas e plugins, eliminando conflitos de versão.
- Refatoração simplificada — alterações em uma biblioteca comum são automaticamente verificadas por todos os módulos dependentes.
- Configuração centralizada — configurações comuns do Gradle, linters e CI/CD são configurados uma vez.
- Commits atômicos — alterações relacionadas em diferentes módulos podem ser feitas em um único commit.
- Reutilização de código — utilitários comuns, DTOs e lógica de negócios ficam facilmente acessíveis a todos os projetos.
Estrutura do monorepositório com Kotlin e Gradle
Vamos considerar a estrutura de diretórios ideal para um monorepositório Kotlin usando Gradle Multi-Module:
my-monorepo/├── build.gradle.kts # Arquivo build raiz├── settings.gradle.kts # Configuração dos módulos├── gradle.properties # Propriedades comuns├── gradle/│ └── libs.versions.toml # Version Catalog├── modules/│ ├── common/ # Utilitários e modelos comuns│ ├── domain/ # Lógica de negócios│ ├── data/ # Camada de dados (API, BD)│ ├── service-a/ # Microsserviço A│ ├── service-b/ # Microsserviço B│ └── shared-test/ # Utilitários de teste comuns├── apps/│ ├── backend/ # Aplicação principal│ └── cli-tool/ # Ferramenta CLI└── config/ ├── checkstyle/ # Configuração de linters └── docker/ # Dockerfile para serviçosConfiguração do settings.gradle.kts
O arquivo settings.gradle.kts define todos os módulos do projeto:
rootProject.name = "my-monorepo"
// Incluímos todos os módulosinclude( ":modules:common", ":modules:domain", ":modules:data", ":modules:service-a", ":modules:service-b", ":apps:backend", ":apps:cli-tool")
// Plugin para gerenciamento de versõespluginManagement { repositories { gradlePluginPortal() mavenCentral() }}Uso do Version Catalog (libs.versions.toml)
Para gerenciamento centralizado de dependências, usamos gradle/libs.versions.toml:
[versions]kotlin = "1.9.22"coroutines = "1.7.3"ktor = "2.3.7"exposed = "0.44.1"
[libraries]kotlin-stdlib = { module = "org.jetbrains.kotlin:kotlin-stdlib", version.ref = "kotlin" }kotlinx-coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "coroutines" }ktor-server-core = { module = "io.ktor:ktor-server-core", version.ref = "ktor" }exposed-core = { module = "org.jetbrains.exposed:exposed-core", version.ref = "exposed" }
[plugins]kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" }kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" }Exemplo de build.gradle.kts para o módulo common
plugins { alias(libs.plugins.kotlin.jvm)}
depend