{"id":28304416,"url":"https://github.com/harmonysoft-tech/custom-gradle-dist-gradle-plugin","last_synced_at":"2025-06-29T12:37:47.537Z","repository":{"id":42235247,"uuid":"151905872","full_name":"harmonysoft-tech/custom-gradle-dist-gradle-plugin","owner":"harmonysoft-tech","description":"Facilitates custom Gradle wrappers construction","archived":false,"fork":false,"pushed_at":"2024-04-22T13:33:23.000Z","size":214,"stargazers_count":10,"open_issues_count":1,"forks_count":3,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-06-08T11:48:18.174Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/harmonysoft-tech.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-10-07T04:27:15.000Z","updated_at":"2025-05-21T05:29:36.000Z","dependencies_parsed_at":"2022-09-17T05:00:17.988Z","dependency_job_id":"7bd229a7-6467-4cdd-90a7-8ae1fa2d7c0b","html_url":"https://github.com/harmonysoft-tech/custom-gradle-dist-gradle-plugin","commit_stats":null,"previous_names":["harmonysoft-tech/custom-gradle-dist-gradle-plugin","denis-zhdanov/custom-gradle-dist-gradle-plugin"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/harmonysoft-tech/custom-gradle-dist-gradle-plugin","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/harmonysoft-tech%2Fcustom-gradle-dist-gradle-plugin","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/harmonysoft-tech%2Fcustom-gradle-dist-gradle-plugin/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/harmonysoft-tech%2Fcustom-gradle-dist-gradle-plugin/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/harmonysoft-tech%2Fcustom-gradle-dist-gradle-plugin/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/harmonysoft-tech","download_url":"https://codeload.github.com/harmonysoft-tech/custom-gradle-dist-gradle-plugin/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/harmonysoft-tech%2Fcustom-gradle-dist-gradle-plugin/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":262596532,"owners_count":23334625,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-05-24T00:12:59.313Z","updated_at":"2025-06-29T12:37:47.510Z","avatar_url":"https://github.com/harmonysoft-tech.png","language":null,"funding_links":["https://www.paypal.com/cgi-bin/webscr?cmd=_donations\u0026business=3GJDPN3TH8T48\u0026lc=EN\u0026item_name=GradleDist\u0026currency_code=USD\u0026bn=PP%2dDonationsBF%3abtn_donateCC_LG%2egif%3aNonHosted"],"categories":[],"sub_categories":[],"readme":"## License\n\nSee the [LICENSE](LICENSE.md) file for license rights and limitations (MIT).\n\n## Overview\n \n This plugin facilitates custom Gradle wrappers construction. For example, we can define [common part](sample/multiple-custom-gradle-distributions/custom-distribution/src/main/resources/init.d/service/service.gradle) which is [shared](sample/multiple-custom-gradle-distributions/client-project/gradle/wrapper/gradle-wrapper.properties#L3) through a custom Gradle distribution and have a terse end-project Gradle setup like [this](sample/multiple-custom-gradle-distributions/client-project/build.gradle) (this is a complete *build.gradle* file):  \n \n ```groovy\nbootRun {\n    main = 'com.mycompany.MyApplication'\n}\n```\n\n## Table of Contents\n\n1. [License](#license)\n2. [Overview](#overview)\n3. [Problem](#problem)\n4. [Solution](#solution)\n5. [Usage](#usage)\n    * [Configure Custom Distribution](#configure-custom-distribution)\n    * [Configure Client Project](#configure-client-project) \n    * [Note About Applying Plugins](#note-about-applying-plugins)\n6. [Examples](#examples)\n7. [Releases](#releases)\n8. [How to Contribute](#how-to-contribute)\n9. [Contributors](#contributors)\n10. [Feedback](#feedback)\n \n## Problem\n \n Gradle scripts quite often contain duplicate parts, that's especially true for micro-service architecture where there are many small servers and each of them has its own repository.\n   \n One solution to that is putting common parts to a Gradle plugin. However, such extension would be specific to particular company and is unlikely to go to the Gradle plugin repository (to allow [shorthand access](https://docs.gradle.org/current/userguide/plugins.html#sec:plugins_block)).  \n That means that it still would be necessary to have a setup like below in every project:  \n ```groovy\n buildscript {\n     repositorirs {\n         maven {\n             url 'http://artifactory.mycompany.com/internalo'\n         }\n         classpath 'com.mycompany:gradle-plugin:3.2.1'\n     }\n }\n \n apply plugin: 'com.mycompany.gradle-plugin'\n\n```\n\n## Solution\n\nGradle automatically applies [init scripts](https://docs.gradle.org/current/userguide/init_scripts.html) from [_Gradle_ wrapper]((https://docs.gradle.org/current/userguide/gradle_wrapper.html))'s _init.d_ directory. That's why we can do the following:\n1. Fetch a 'pure' _Gradle_ distribution of particular version\n2. Put our scripts with common logic into it's _init.d_ directory\n3. Store that modified _Gradle_ distribution in our repository\n4. Reference that distribution from the _Gradle Wrapper_ config in our projects    \n \n## Usage\n\n### Configure Custom Distribution\n\n1. Create new Gradle project (an empty *build.gradle*) \n2. Register the plugin there:\n    ```groovy\n    plugins {\n        id 'tech.harmonysoft.oss.custom-gradle-dist-plugin' version '1.11.0'\n    }\n    ```\n 3. Specify target settings in the `gradleDist {}` block.  \n     **mandatory settings:**\n     * `gradleVersion` - base Gradle wrapper version\n     * `customDistributionVersion` - custom distribution version (`project.version` is used by default)\n     * `customDistributionFileNameMapper` - a property of type [CustomDistributionNameMapper](./src/main/kotlin/tech/harmonysoft/oss/gradle/dist/config/CustomDistributionNameMapper.kt) which generates resulting custom distribution file name for the given parameters. *Note: it's necessary to specify this property or `distributionNameMapper` property. It's an error to define the both/none of them*\n       * `gradleVersion` - base gradle distribution version as defined above\n       * `customDistributionVersion` - custom distribution mixing version as defined above\n       * `gradleDistributionType` - gradle distribution type as defined below\n       * `distributionName` - nullable string - it's `null` in case client project produces a single custom Gradle distribution; non-`null` distribution name when multiple custom Gradle distributions are produced\n\n        we configure it in `build.gradle.kts` as below:\n        ```\n        import tech.harmonysoft.oss.gradle.dist.config.CustomDistributionNameMapper\n        ...\n        gradleDist {\n            customDistributionFileNameMapper = CustomDistributionNameMapper {\n                gradleVersion: String, customDistributionVersion: String, distributionType: String, distributionName: String? -\u003e\n                    \"${\"$\"}{distributionType}-custom-${\"$\"}{customDistributionVersion}-base-${\"$\"}{gradleVersion}.zip\"\n            }\n        }\n        ```\n       this is how it can be configured in `build.gradle`:\n       ```\n       import tech.harmonysoft.oss.gradle.dist.config.CustomDistributionNameMapper\n       ...\n       gradleDist {\n           customDistributionFileNameMapper = { gradleVersion, customDistributionVersion, distributionType, distributionName -\u003e\n               \"${\"$\"}{distributionType}-custom-${\"$\"}{customDistributionVersion}-base-${\"$\"}{gradleVersion}.zip\"\n           } as CustomDistributionNameMapper\n       }\n       ```\n     * `customDistributionName` - a unique identifier for the custom Gradle distribution. If this property is defined, then resulting file name is `gradle-\u003cgradleVersion\u003e-\u003ccustomDistributionName\u003e-\u003ccustomDistributionVersion\u003e-\u003cgradleDistributionType\u003e.zip`, e.g. `gradle-8.4-my-company-1.2.3-bin.zip`. I.e. these two setups are the same:\n       ```\n       gradleDist {\n           ...\n           customDistributionName = \"my-company\"\n       }\n       ```\n       and\n       ```\n       gradleDist {\n           ...\n           customDistributionFileNameMapper = { gradleVersion, customDistributionVersion, gradleDistributionType, distributionName -\u003e\n               val prefix = \"gradle-$gradleVersion-${config.customDistributionName.get()}-$customDistributionVersion\"\n                val suffix = \"$gradleDistributionType.zip\"\n                distributionName?.let {\n                    \"$prefix-$it-$suffix\"\n                } ?: \"$prefix-$suffix\"\n           }\n       }\n       ```\n       *Note: it's necessary to specify this property or `customDistributionFileNameMapper` property. It's an error to define the both/none of them*\n    \n    * `initScriptsSourceDir` - a path to the directory where your initialization scripts are located (see below docs for more details). The path to the directory must be set, and the pointed directory must exist. The default path is `src/main/resources/init.d`.\n     \n     **optional settings:**\n     * `gradleDistributionType` - allows to specify base Gradle distribution type. `bin` and `all` [are available](https://docs.gradle.org/current/userguide/gradle_wrapper.html#sec:adding_wrapper) at the moment, `bin` is used by default\n     * `utilityScriptsSourceDir` - a path to the directory where your utility scripts and replacements are located (see below docs for more details). The path to the directory is optional, but the pointed directory must exist. The default path is `src/main/resources/include`.\n     * `skipContentExpansionFor` - the plugin by default expands content of the files included into custom Gradle distribution by default (see below). That might cause a problem if we want to add some binary file like `*.jar` or `*.so`. This property holds a list of root paths relative to `init.d` which content shouldn't be expanded.  \n       Example: consider the following project structure:\n       ```\n       init.d\n         |__my.gradle\n         |\n         |__bin\n             |\n             |__profiler\n                   |\n                   |__agent.jar\n                         |\n                         |__linux-x64\n                               |\n                               |__agentti.so\n       ```\n       Here we want to expand content for `my.gradle`, but don't touch `bin/profiler/agent.jar` and `bin/profiler/linux-x64/agentti.so`. We can configure it as below:\n       ```\n       gradleDist {\n         ...\n         skipContentExpansionFor = listOf(\"bin/profiler\")\n       }\n       ```\n     * `rootUrlMapper` - a property of type [GradleUrlMapper](./src/main/kotlin/tech/harmonysoft/oss/gradle/dist/config/GradleUrlMapper.kt) which allows to build an url to the root base Gradle distribution path. This property is convenient in restricted environments where *https://service.gradle.org* is unavailable. We can deploy target Gradle distribution to a server inside the private network then and use it as a base for our custom Gradle distributions. The function receives the following arguments:  \n       * `version` - target base Gradle distribution version, e.g. *5.1*\n       * `type` - target base Gradle distribution type, e.g. `bin`  \n       \n       Following implementation is used by default (`build.gradle.kts`):\n\n       ```\n       import tech.harmonysoft.oss.gradle.dist.config.GradleUrlMapper\n       ...\n       gradleDist {\n           ...\n           rootUrlMapper = GradleUrlMapper { version: String, type: String -\u003e\n               \"https://services.gradle.org/distributions/gradle-${version}-${type}.zip\"\n           }\n       }\n       ```\n       \n       `build.gradle` syntax for the same:\n       ```\n       import tech.harmonysoft.oss.gradle.dist.config.GradleUrlMapper\n       ...\n       gradleDist {\n         ...\n         rootUrlMapper = { version, type -\u003e\n             \"https://services.gradle.org/distributions/gradle-${version}-${type}.zip\"\n         } as GradleUrlMapper\n       }\n       ```\n     \n    Resulting *build.gradle* might look like below:  \n    ```groovy\n    plugins {\n        id 'tech.harmonysoft.oss.custom-gradle-dist-plugin' version '1.11.0'\n    }\n    \n    gradleDist {\n        gradleVersion = '4.10'\n        customDistributionVersion = '1.0'\n        customDistributionName = 'my-project'\n    }\n    ```\n4. Define common setup to be included to the custom Gradle distribution in the project's `src/main/resources/init.d` directory  \n    \n    Note that the plugin supports simple text processing engine - it's possible to put utility scripts to the `src/main/resources/include`. Their content is applied to files from `src/main/resources/init.d` using `$utility-script-name$` syntax.  \n    \n    For example, we can have a file `src/main/resources/init.d/setup.gradle`:  \n    ```groovy\n    allprojects {\n        $dependencies$\n    }\n    ```\n    \n    and the following files in the `src/main/resources/include` directory:  \n    * `src/main/resources/include/dependencies.gradle`:  \n        ```groovy\n        dependencies {\n            compile 'com.fasterxml.jackson.core:jackson-core:$jackson-version$'\n            compile 'com.fasterxml.jackson.module:jackson-module-kotlin:$jackson-version$'\n        }\n        ```  \n    \n    * `src/main/resources/include/jackson-version.gradle`:  \n        ```groovy\n        2.9.6\n        ```  \n    \n    When custom Gradle distribution is created, its `init.d` directory has `setup.gradle` file with the following content then:  \n    \n    ```groovy\n    allprojects {\n        compile 'com.fasterxml.jackson.core:jackson-core:2.9.6'\n        compile 'com.fasterxml.jackson.module:jackson-module-kotlin:2.9.6'  \n    }\n    ```  \n    \n    Note that text processing might be nested, i.e. files from `src/main/resources/include` might refer to another files from the same directory through the `$file-name$` syntax.\n\n    Also, we can put any replacements into file `src/main/resources/include/replacements.properties`. Example:\n\n    `include/replacements.properties`\n    ```\n    spring.plugin.version = 3.1.5\n    spring.dependency.management.plugin.version = 1.1.3\n    ```\n   \n    `init.d/mixin.gradle`\n    ```\n    initscript {\n        dependencies {\n            classpath 'org.springframework.boot:spring-boot-gradle-plugin:$spring.plugin.version$'\n            classpath 'io.spring.gradle:dependency-management-plugin:$spring.dependency.management.plugin.version$'\n        }\n    }\n    ```\n    \n    There is an alternative setup where we want to produce more than one Gradle wrapper distribution (e.g. `android` and `server`). In this situation corresponding directories should be created in the `src/main/resources/init.d`:  \n    ```\n    src\n     |__ main\n         |__ resources\n                 |__ init.d\n                       |__ android\n                       |      |__ android-setup.gradle\n                       |\n                       |__ server\n                              |__ server-setup.gradle   \n    ```  \n    \n    Here is what we have after the build:  \n    ```\n    build\n      |__ gradle-dist\n               |__ gradle-4.10-my-project-1.0-android.zip\n               |\n               |__ gradle-4.10-my-project-1.0-server.zip\n    ```\n    \n5. Build Gradle distribution(s)\n\n    ```\n    ./gradlew buildGradleDist\n    ```\n    \n    The distribution(s) are located in the `build/gradle-dist`\n\n6. In addition, if you need, you can configure the properties of the `buildGradleDist` task, such as the path to the directory where downloaded Gradle distributions and built custom Gradle distributions should be located.  You can do this as follows:\n    ```groovy\n    import tech.harmonysoft.oss.gradle.dist.BuildCustomGradleDistributionTask\n   \n    tasks.named('buildGradleDist', BuildCustomGradleDistributionTask) {\n        gradleDownloadDir = project.layout.buildDirectory.dir('own-gradle-download') \n        customDistributionOutputDir = project.layout.buildDirectory.dir('own-gradle-dist') \n    }\n    ```\n\n### Configure Client Project\n\nJust define your custom Gradle wrapper's location in the *gradle/wrapper/gradle-wrapper.properties* file:  \n```properties\ndistributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\ndistributionUrl=http\\://mycompany.com/repository/chillout-release/com/mycompany/gradle-dist/gradle-4.10-my-project-1.0.zip\n```\n\n### Note About Applying Plugins\n\nIt's quite possible that we would like to apply common plugins in init scripts, e.g. our projects are all java and we want to specify `apply plugin: 'java'` in the init script.\n  \nUnfortunately, there is a known [old bug](https://github.com/gradle/gradle/issues/1322) in Gradle that non-bundled plugins can't be applied by id in init script.  \n\nA solution is to apply them by fully qualified class name.  \n\nE.g. given 'normal' plugins configuration:\n\n```groovy\napply plugin: 'org.jetbrains.kotlin.jvm'\napply plugin: 'org.springframework.boot'\napply plugin: 'io.spring.dependency-management'\napply plugin: \"com.jfrog.artifactory\"\n```\n\nWe should configure them like below in init script:  \n\n```groovy\nallprojects {\n    apply plugin: org.jetbrains.kotlin.gradle.plugin.KotlinPlatformJvmPlugin\n    apply plugin: org.springframework.boot.gradle.plugin.SpringBootPlugin\n    apply plugin: io.spring.gradle.dependencymanagement.DependencyManagementPlugin\n    apply plugin: org.jfrog.gradle.plugin.artifactory.ArtifactoryPlugin\n}\n```\n\n## Examples\n\nComplete working examples can be found [here](sample/README.md).\n\n## Releases\n\n[Release Notes](RELEASE.md).  \n\nThe latest plugin version can be found [here](https://plugins.gradle.org/plugin/tech.harmonysoft.oss.custom-gradle-dist-plugin).\n\n## How to Contribute\n\n* [report a problem/ask for enhancement](https://github.com/harmonhsoft-tech/custom-gradle-dist-gradle-plugin/issues)\n* [submit a pull request](https://github.com/harmonhsoft-tech/custom-gradle-dist-gradle-plugin/pulls)\n* [![paypal](https://www.paypalobjects.com/en_US/i/btn/btn_donateCC_LG.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_donations\u0026business=3GJDPN3TH8T48\u0026lc=EN\u0026item_name=GradleDist\u0026currency_code=USD\u0026bn=PP%2dDonationsBF%3abtn_donateCC_LG%2egif%3aNonHosted)\n\n## Contributors\n\n* [Denis Zhdanov](https://github.com/denis-zhdanov)\n\n## Feedback\n\nPlease use any of the channels below to provide your feedback, it's really valuable for me:\n* [email](mailto:denzhdanov@gmail.com)","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fharmonysoft-tech%2Fcustom-gradle-dist-gradle-plugin","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fharmonysoft-tech%2Fcustom-gradle-dist-gradle-plugin","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fharmonysoft-tech%2Fcustom-gradle-dist-gradle-plugin/lists"}