Giter Site home page Giter Site logo

auto-module's Introduction

Auto Module

Actions Gradle Plugin Portal

This Gradle plugin helps with module dependencies. And by help, it means it does the hard work for you.

Why do I need this?

So, these are some (but not all) of the reasons why you should use this:

  • Avoid user error: It's quite common, specially with complex projects, to have a large and nested project graph with all the available modules. Updating it can be tedious and, frankly, you probably rather be doing other things.
  • Type safety: After you rename a module, any reference to it will complain when evaluating the project's build, so you know where you need to change your dependencies.
  • IDE Auto-complete: One of the benefits of using kts build scripts is that the IDE can provide auto complete. This will save you multiple trips to the settings.gradle[.kt] script or the project structure to remember the name of the module you are looking for.
  • Progressive upgrade: It has support for Groovy gradle so you don't have to migrate all your modules to use kts if you are not quite there yet or don't need it on all of them.
  • Module generation: You can define tasks that can be used from command line to generate a predefined module structure with the provided template. The IDE only allows to create modules in the root of the project, this allows to create it on any directory as well as provide the means for templating how certain modules are defined.

How do I use it?

Remove all your include() instructions inside settings.gradle[.kts] and add this:

plugins {
    id("com.pablisco.gradle.automodule") version "0.12"
}

That's it!

At least from the settings script sense. Now you will probably want to convert all the local project dependencies to use the type safe graph!

If you have a project with the following structure:

root
+-- app
\-- features
    +-- home
    \-- settings

AutoModule generates a build module in .gradle/automodule with code similar to this:

object autoModules {
    val app = App
    object App : AutoModuleDependency by autoModuleDependency(":app")
    val features = Features
    object Features : AutoModuleDependency by autoModuleDependency(":features") {
        val home = Home
        object Home : AutoModuleDependency by autoModuleDependency(":features:home")
        object settings : AutoModuleDependency by autoModuleDependency(":features:settings")
    }
}

This will be accessible from any module, so you can add dependencies like:

implementation(project(autoModules.features.home)

Ignore modules

If you want to make sure a module is not included to the Gradle graph you can do it in two ways:

  1. Adding the .ignore extension at the end of the build.gradle[.kts] script.
  2. Inside settings.gradle[.kts] you can configure autoModule to do so:
autoModule {
  ignore(":modulePath", ":some:other:module")
}

Legacy Groovy Script support

When you have a large project, it may not be possible to migrate all your scripts to Kotlin. However, you can use the same semantics as you have in Kotlin with Groovy scripts:

implementation(autModules.features.home)

This allows you to have a smooth migration to Kotlin Scripts in the future but remain with minimum changes in the meantime.

If you want to keep using Gradle with Groovy scripts, instead of Kotlin, this plugin will still work. However, you still need to add support for kotlin scripts in buildSrc/build.gradle.

Module generation tasks

You can define tasks that can be used from command line to generate new modules:

autoModule {
    template(
        path = Paths.get("features"), //optional, default is root
        type = "feature"
    ) { // this: ApplyTemplateScope
        file("build.gradle.kts", contents = """
            plugins { 
                kotlin("jvm") version kotlin_version 
            }

            name = "com.example.$templateDirectory"    

            dependencies {
                implementation(local.core)
            }
        """.trimIndent())
        "src" { 
            folder("main/kotlin")
            folder("test/kotlin")
        }   
    }   
}

This generates a task called createFeatureModule that you can use from command line like this:

./gradlew createFeatureModule --templateDirectory=settings

Calling that task will create a new module inside $rootDir/features/settings/ with the defined files and directories.

Since modules are included with each sync, AutoModule will also add this new module to the graph and you are ready to use it straight away.

If you want to change the target directory where the module is to be created you can also add the path parameter in command line:

./gradlew createFeatureModule --templateDirectory=settings --workingDirectory=notFeature

The "body" of the template function is a lambda that has a receiver of type ApplyTemplateScope. This scope exposes a FileTreeScope (by delegation) as well as templateDirectory, workingDirectory and properties.

  • Template Directory: The name of the folder where we are starting to write our template.
  • Working Directory: The place the module is going to be written. By default this one is the root directory for the current project.
  • Properties: These are the project's properties. These can be defined in the project's gradle.properties or the user one defined in ~/.gradle/gradle.properties. Additionally you can include extra properties via command line like -Pkey=value.

The first two can be accessed directly inside the lambda. Properties is a simple Map<String, String> so we can access the values normally: properties["package"]

History

All this started with this Gist:

https://gist.github.com/pablisco/e50c792f1febb77af0fbc2d4f8f2810e

And this tweet:

https://twitter.com/pablisc0/status/1227933148622860289

Couple of weeks of sleepless evenings, and auto-module was born.

License

This project is licensed under the MIT License - see the license.md file for details

auto-module's People

Contributors

pablisco avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.