$ show grab/grazel
Grazel is a Gradle plugin that migrates Android projects from Gradle to Bazel build systems. It analyzes Gradle project configuration, extracts Android-specific information (dependencies, variants, resources, manifest), and generates equivalent Bazel BUILD and WORKSPACE files. The plugin supports incremental migration, allowing parts of a project to use Bazel while others remain on Gradle. Architecture follows Gradle plugin conventions with modular separation: core plugin implementation, extension points for configuration, dependency analysis/resolution components, Android-specific extraction logic, Bazel rule generation using a type-safe Kotlin DSL for Starlark, and task management for orchestrating the migration process. Dependency injection via Dagger/Hilt ensures loose coupling and testability.
The LLM identified 4 files worth highlighting for reuse:
Typesafe Kotlin DSL for generating Bazel Starlark code. Provides classes like StatementsBuilder, AssignStatement, FunctionCall that allow building Bazel BUILD file content with compile-time safety. Instead of string concatenation, uses Kotlin's type system to ensure syntactically correct output. This pattern solves the universal problem of generating structured text with guarantees and could be extracted for any code generation task.
Complete dependency resolution and conversion system. Handles resolving Gradle dependencies to actual artifacts, converting to Bazel-compatible format, managing transitive dependencies, and resolving version conflicts. Features topological sorting, dependency graph construction, and resolution caching. Demonstrates clean separation between collection, resolution, and conversion phases with sophisticated caching mechanisms.
Android variant handling and compression system. Manages the complexity of build types, product flavors, and build variants. Provides equivalence checking and compression strategies to minimize Bazel target proliferation. Models Android variants, determines when variants can be merged, and implements algorithms to reduce target count while preserving build semantics. Addresses the combinatorial complexity of Android build configurations.
Dagger-based dependency injection framework implementation. Shows excellent practices for structuring a large Gradle plugin with clear separation of concerns. Provides well-defined components and modules that make the code highly testable and maintainable. Demonstrates how to properly apply DI in a Gradle plugin context for loose coupling and ease of testing.