├── .gitignore ├── .travis.yml ├── LICENSE ├── README.md ├── build.gradle ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── settings.gradle └── src ├── integrationTest └── groovy │ └── com │ └── gorylenko │ └── SLF4JBindingPostShadowTest.groovy ├── main ├── groovy │ └── com │ │ └── gorylenko │ │ ├── GenerateGitPropertiesTask.groovy │ │ ├── GitProperties.groovy │ │ ├── GitPropertiesPlugin.groovy │ │ ├── PropertiesFileWriter.groovy │ │ ├── properties │ │ ├── AbstractGitProperty.groovy │ │ ├── BranchProperty.groovy │ │ ├── BuildHostProperty.groovy │ │ ├── BuildUserEmailProperty.groovy │ │ ├── BuildUserNameProperty.groovy │ │ ├── BuildVersionProperty.groovy │ │ ├── CacheSupport.groovy │ │ ├── ClosestTagCommitCountProperty.groovy │ │ ├── ClosestTagNameProperty.groovy │ │ ├── CommitIdAbbrevProperty.groovy │ │ ├── CommitIdDescribeProperty.groovy │ │ ├── CommitIdProperty.groovy │ │ ├── CommitMessageFullProperty.groovy │ │ ├── CommitMessageShortProperty.groovy │ │ ├── CommitTimeProperty.groovy │ │ ├── CommitUserEmailProperty.groovy │ │ ├── CommitUserNameProperty.groovy │ │ ├── DirtyProperty.groovy │ │ ├── RemoteOriginUrlProperty.groovy │ │ ├── TagsProperty.groovy │ │ └── TotalCommitCountProperty.groovy │ │ └── writer │ │ └── SkipPropertiesCommentsOutputStream.groovy ├── java │ └── com │ │ └── gorylenko │ │ └── writer │ │ └── NormalizeEOLOutputStream.java └── resources │ └── META-INF │ └── gradle-plugins │ └── com.gorylenko.gradle-git-properties.properties └── test ├── groovy └── com │ └── gorylenko │ ├── BackwardCompatibilityFunctionalTest.groovy │ ├── BasicFunctionalTest.groovy │ ├── BuildCacheFunctionalTest.groovy │ ├── BuildSrcFunctionalTest.groovy │ ├── ConfigurationCacheFunctionalTest.groovy │ ├── GitPropertiesPluginTests.groovy │ ├── GitPropertiesTest.groovy │ ├── PropertiesFileWriterTest.groovy │ ├── properties │ ├── BranchPropertyTest.groovy │ ├── BuildHostPropertyTest.groovy │ ├── BuildUserEmailPropertyTest.groovy │ ├── BuildUserNamePropertyTest.groovy │ ├── BuildVersionPropertyTest.groovy │ ├── ClosestTagCommitCountPropertyTest.groovy │ ├── ClosestTagNamePropertyTest.groovy │ ├── CommitIdAbbrevPropertyTest.groovy │ ├── CommitIdDescribePropertyTest.groovy │ ├── CommitIdPropertyTest.groovy │ ├── CommitMessageFullPropertyTest.groovy │ ├── CommitMessageShortPropertyTest.groovy │ ├── CommitTimePropertyTest.groovy │ ├── CommitUserEmailPropertyTest.groovy │ ├── CommitUserNamePropertyTest.groovy │ ├── DirtyPropertyTest.groovy │ ├── GitRepositoryBuilder.groovy │ ├── RemoteOriginUrlPropertyTest.groovy │ ├── TagsPropertyTest.groovy │ └── TotalCommitCountPropertyTest.groovy │ └── writer │ ├── NormalizeEOLOutputStreamTest.groovy │ └── SkipPropertiesCommentsOutputStreamTest.groovy └── resources └── shallowclone3.zip /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | ### Java template 3 | *.class 4 | 5 | # Package Files # 6 | *.jar 7 | *.war 8 | *.ear 9 | 10 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 11 | hs_err_pid* 12 | 13 | ### JetBrains template 14 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion 15 | *.ids 16 | *.iml 17 | 18 | ## Directory-based project format: 19 | .idea/ 20 | 21 | ## File-based project format: 22 | *.ipr 23 | *.iws 24 | 25 | ## Plugin-specific files: 26 | 27 | # IntelliJ 28 | /out/ 29 | 30 | # STS 31 | .apt_generated 32 | .classpath 33 | .factorypath 34 | .project 35 | .settings 36 | .springBeans 37 | .sts4-cache 38 | /target/ 39 | /bin/ 40 | 41 | # NetBeans 42 | /nbproject/private/ 43 | /build/ 44 | /nbbuild/ 45 | /dist/ 46 | /nbdist/ 47 | /.nb-gradle/ 48 | 49 | ## Gradle template 50 | .gradle 51 | build/ 52 | 53 | # Ignore Gradle GUI config 54 | gradle-app.setting 55 | 56 | # Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) 57 | !gradle-wrapper.jar 58 | 59 | ## mac 60 | .DS_Store 61 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: java 2 | jdk: 3 | - openjdk8 4 | - openjdk9 5 | - openjdk10 6 | - openjdk11 7 | - openjdk12 8 | - openjdk13 9 | - openjdk14 10 | - openjdk15 11 | - openjdk16 12 | before_cache: 13 | - rm -f $HOME/.gradle/caches/modules-2/modules-2.lock 14 | - rm -fr $HOME/.gradle/caches/*/plugin-resolution/ 15 | cache: 16 | directories: 17 | - $HOME/.gradle/caches/ 18 | - $HOME/.gradle/wrapper/ 19 | install: true 20 | script: 21 | - ./gradlew --scan build 22 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## about 2 | 3 | This Gradle plugin can be used for generating `git.properties` file generation for Git-based projects (similar to maven git commit id plugin). It can be used for (but not limited to) Spring Boot apps. 4 | Plugin is available from [Gradle Plugins repository](https://plugins.gradle.org/plugin/com.gorylenko.gradle-git-properties). 5 | 6 | Idea - @lievendoclo, originally published in article [Spring Boot's info endpoint, Git and Gradle - InsaneProgramming](http://www.insaneprogramming.be/article/2014/08/15/spring-boot-info-git/). 7 | 8 | [![Build Status](https://travis-ci.org/n0mer/gradle-git-properties.svg?branch=master)](https://travis-ci.org/n0mer/gradle-git-properties) 9 | 10 | ## compatibility matrix 11 | 12 | This Gradle plugin is compatible with the following versions of Gradle: 13 | 14 | | Plugin version | Min. Gradle version | 15 | | -------------- | ------------------- | 16 | | 2.3.2 | 5.1 | 17 | | 2.2.4 | 4.x | 18 | 19 | ## notes 20 | * Plugin requires Java 8+ 21 | * If `git.properties` is missing on Gradle 5.1.x and 5.2.x [Issue 128](https://github.com/n0mer/gradle-git-properties/issues/128), use `gitPropertiesResourceDir` to config a different output directory 22 | * Since gradle-git-properties v2.x, we require JGit 5.x, this might cause some issues if you have other gradle plugin which uses JGit 1.4.x. In that case, you can use gradle-git-properties v1.5.x (instead of 2.x) which uses JGit 1.4.x. See [Issue 133](https://github.com/n0mer/gradle-git-properties/issues/133) for more info about this plugin's dependencies 23 | * With gradle-git-properties v2.2.4, v2.3.0, and v2.3.1, grgit v4.1.0 always requires the latest JGit which can be 6+, this cause build fails if you run Gradle with Java under 11. See [Issue 195](https://github.com/n0mer/gradle-git-properties/issues/195) for more info about this issue 24 | 25 | ## usage 26 | 27 | Declare this in your `build.gradle` 28 | 29 | ```groovy 30 | plugins { 31 | id "com.gorylenko.gradle-git-properties" version "2.5.0" 32 | } 33 | ``` 34 | 35 | A `git.properties` file will be generated when building Java-based projects (the plugin will configure any existing `classes` task to depend on `generateGitProperties` task - which is responsible for generated `git.properties` file). For non-Java projects, `generateGitProperties` task must be executed explicitly to generate `git.properties` file. The git repository for the project will be used. 36 | 37 | Spring Boot specific info: This is enough to see git details via `info` endpoint of [spring-boot-actuator](http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#production-ready). 38 | 39 | If needed - override folder and file name of the generated file using `gitPropertiesName` and `gitPropertiesResourceDir` config keys. 40 | (NOTE: By default, the file will be generated at `build/resources/main/git.properties`) 41 | 42 | ```groovy 43 | gitProperties { 44 | // Customize file name (could be a file name or a relative file path below gitPropertiesResourceDir dir) 45 | gitPropertiesName = "my-git-file.properties" 46 | 47 | // Customize directory using gitPropertiesResourceDir config 48 | // The directory in this config key is also added as a classpath entry 49 | // (so the git.properties file will be included in the final JAR file) 50 | gitPropertiesResourceDir = "${project.rootDir}/my/generated-resources-dir" 51 | 52 | // (Deprecated, for compatibility only) 53 | // Customize directory using gitPropertiesDir config 54 | gitPropertiesDir = "${project.rootDir}/your/custom/dir" 55 | } 56 | ``` 57 | > Please note that `spring-boot-actuator` expects `git.properties` to be available at certain location. 58 | 59 | If needed - use `dateFormat` and `dateFormatTimeZone` to format `git.commit.time` property (See [SimpleDateFormat](http://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html) and [TimeZone](http://docs.oracle.com/javase/7/docs/api/java/util/TimeZone.html) for valid values) 60 | 61 | ```groovy 62 | gitProperties { 63 | dateFormat = "yyyy-MM-dd'T'HH:mmZ" 64 | dateFormatTimeZone = "PST" 65 | } 66 | ``` 67 | 68 | Note: Kotlin DSL syntax 69 | ```kotlin 70 | configure { dateFormat = "yyyy-MM-dd'T'HH:mmZ" } 71 | ``` 72 | 73 | If needed - use `branch` to override git branch name (when it cannot be detected correctly from environment variables/working directory) 74 | 75 | ```groovy 76 | gitProperties { 77 | branch = System.getenv('GIT_BRANCH') 78 | } 79 | ``` 80 | 81 | 82 | By default, all git properties which are supported by the plugin will be generated: 83 | 84 | ``` 85 | git.branch 86 | git.build.host 87 | git.build.user.email 88 | git.build.user.name 89 | git.build.version 90 | git.closest.tag.commit.count 91 | git.closest.tag.name 92 | git.commit.id 93 | git.commit.id.abbrev 94 | git.commit.id.describe 95 | git.commit.message.full 96 | git.commit.message.short 97 | git.commit.time 98 | git.commit.user.email 99 | git.commit.user.name 100 | git.dirty 101 | git.remote.origin.url 102 | git.tags 103 | git.total.commit.count 104 | ``` 105 | You can have more fine-grained control of the content of `git.properties` using `keys`: 106 | 107 | ```groovy 108 | gitProperties { 109 | keys = ['git.branch','git.commit.id','git.commit.time'] 110 | } 111 | ``` 112 | 113 | Custom properties can be added with `customProperty` (supports both expressions and closures): 114 | 115 | ```groovy 116 | gitProperties { 117 | customProperty 'greeting', 'Hello' // expression 118 | customProperty 'my_custom_git_id', { it.head().id } // closure, 'it' is an instance of org.ajoberstar.grgit.Grgit 119 | customProperty 'project_version', { project.version } // closure 120 | } 121 | ``` 122 | 123 | You can also replace standard properties using `customProperty`. In the below example, the logic `it.describe(tags: true)` will replace the plugin's logic which using `describe(tags: false)` 124 | 125 | ```groovy 126 | gitProperties { 127 | // using any tags (not limited to annotated tags) for "git.commit.id.describe" property 128 | // see http://ajoberstar.org/grgit/grgit-describe.html for more info about the describe method and available parameters 129 | // 'it' is an instance of org.ajoberstar.grgit.Grgit 130 | customProperty 'git.commit.id.describe', { it.describe(tags: true) } 131 | } 132 | ``` 133 | 134 | 135 | > Spring Boot specific info: By default, the `info` endpoint exposes only `git.branch`, `git.commit.id`, and `git.commit.time` properties (even then there are more in your `git.properties`). 136 | > In order to expose all available properties, set the "management.info.git.mode" property to "full" per [the Spring Boot documentation](https://docs.spring.io/spring-boot/docs/current/reference/html/production-ready-endpoints.html#production-ready-application-info-git), e.g. in application.properties: 137 | > ``` 138 | > management.info.git.mode=full 139 | > ``` 140 | 141 | 142 | If the `.git` directory is not located in the same directory as the Gradle project, you will need to specify it using `dotGitDirectory`: 143 | 144 | ```groovy 145 | gitProperties { 146 | // if .git directory is on the same level as the root project 147 | dotGitDirectory = project.rootProject.layout.projectDirectory.dir(".git") 148 | 149 | // if .git directory is in a different location 150 | dotGitDirectory = "${project.rootDir}/../somefolder/.git" 151 | } 152 | ``` 153 | 154 | If for some reason, the `.git` directory for the project doesn't exist, and you don't want the task to fail in that case, use `failOnNoGitDirectory=false`: 155 | 156 | ```groovy 157 | gitProperties { 158 | failOnNoGitDirectory = false 159 | } 160 | ``` 161 | 162 | To skip plugin execution completely, configure the `enabled` property: 163 | 164 | ```groovy 165 | tasks.withType(com.gorylenko.GenerateGitPropertiesTask).all { enabled = false } 166 | ``` 167 | 168 | ## result from `info` endpoint (if used with Spring Boot apps) 169 | 170 | When using with Spring Boot: This is raw `JSON` from `info` endpoint (with `management.info.git.mode=simple` or not configured): 171 | 172 | ```json 173 | { 174 | "git": { 175 | "commit": { 176 | "time": "2018-03-28T05:13:53Z", 177 | "id": "32ff212" 178 | }, 179 | "branch": "Fix_issue_68" 180 | } 181 | } 182 | ``` 183 | 184 | This is raw `JSON` from `info` endpoint (with `management.info.git.mode=full`): 185 | 186 | ```json 187 | { 188 | "git": { 189 | "build": { 190 | "host": "myserver-1", 191 | "version": "0.0.1-SNAPSHOT", 192 | "user": { 193 | "name": "First Last", 194 | "email": "username1@example.com" 195 | } 196 | }, 197 | "branch": "Fix_issue_68", 198 | "commit": { 199 | "message": { 200 | "short": "Fix issue #68", 201 | "full": "Fix issue #68" 202 | }, 203 | "id": { 204 | "describe": "v1.4.21-28-g32ff212-dirty", 205 | "abbrev": "32ff212", 206 | "full": "32ff212b9e2873fa4672f1b5dd41f67aca6e0731" 207 | }, 208 | "time": "2018-03-28T05:13:53Z", 209 | "user": { 210 | "email": "username1@example.com", 211 | "name": "First Last" 212 | } 213 | }, 214 | "closest": { 215 | "tag": { 216 | "name": "v1.4.21", 217 | "commit": { 218 | "count": "28" 219 | } 220 | } 221 | }, 222 | "dirty": "true", 223 | "remote": { 224 | "origin": { 225 | "url": "git@github.com:n0mer/gradle-git-properties.git" 226 | } 227 | }, 228 | "tags": "", 229 | "total": { 230 | "commit": { 231 | "count": "93" 232 | } 233 | } 234 | } 235 | } 236 | ``` 237 | 238 | ### other usages 239 | 240 | This plugin can also be used for other purposes (by configuring `extProperty` to keep generated properties and accessing the properties from `project.ext`). 241 | 242 | Note that the `git.properties` file is always generated and currently there is no option to disable it. 243 | Please also make sure that the `generateGitProperties` task is executed before accessing the generated properties. 244 | 245 | In the below example, `printGitProperties` will print `git.commit.id.abbrev` property when it is executed: 246 | 247 | ```groovy 248 | gitProperties { 249 | extProperty = 'gitProps' // git properties will be put in a map at project.ext.gitProps 250 | } 251 | generateGitProperties.outputs.upToDateWhen { false } // make sure the generateGitProperties task always executes (even when git.properties is not changed) 252 | 253 | task printGitProperties(dependsOn: 'generateGitProperties') { // make sure generateGitProperties task to execute before accessing generated properties 254 | doLast { 255 | println "git.commit.id.abbrev=" + project.ext.gitProps['git.commit.id.abbrev'] 256 | } 257 | } 258 | ``` 259 | 260 | Below is another example about using generated properties for `MANIFEST.MF` of a Spring Boot webapp (similar can be done for non Spring apps). Note the usage of `GString` lazy evaluation to delay evaluating `project.ext.gitProps['git.commit.id.abbrev']` until `MANIFEST.MF` is created. Because `generateGitProperties` task will always execute automatically before any `classes` task (in Java projects), no `dependsOn` is needed for `bootJar` task. 261 | 262 | ```groovy 263 | gitProperties { 264 | extProperty = 'gitProps' // git properties will be put in a map at project.ext.gitProps 265 | } 266 | generateGitProperties.outputs.upToDateWhen { false } // make sure the generateGitProperties task always executes (even when git.properties is not changed) 267 | 268 | bootJar { 269 | manifest { 270 | attributes( 271 | 'Build-Revision': "${-> project.ext.gitProps['git.commit.id.abbrev']}" // Use GString lazy evaluation to delay until git properties are populated 272 | ) 273 | } 274 | } 275 | ``` 276 | 277 | Note: Kotlin DSL syntax (similar to above `GString` example) 278 | ```kotlin 279 | // [...] 280 | put("Implementation-Version", object { 281 | override fun toString():String = (project.extra["gitProps"] as Map)["git.commit.id"]!! 282 | }) 283 | // [...] 284 | ``` 285 | ## more notes 286 | 287 | If you need to use a specific JGit version (e.g. because of version conflict), check the below example: 288 | 289 | ```groovy 290 | buildscript { 291 | repositories { 292 | maven { 293 | url "https://plugins.gradle.org/m2/" 294 | } 295 | } 296 | dependencies { 297 | classpath ("com.gorylenko.gradle-git-properties:gradle-git-properties:2.5.0") { 298 | exclude group: 'org.eclipse.jgit', module: 'org.eclipse.jgit' // remove plugin's jgit dependency 299 | } 300 | classpath 'org.eclipse.jgit:org.eclipse.jgit:5.5.0.201909110433-r' // use the specified jgit dependency 301 | } 302 | } 303 | 304 | apply plugin: "com.gorylenko.gradle-git-properties" 305 | 306 | apply plugin: 'java' 307 | ``` 308 | ## license 309 | 310 | `gradle-git-properties` is Open Source software released under the [Apache 2.0 license](http://www.apache.org/licenses/LICENSE-2.0.html) 311 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | import com.github.jengelman.gradle.plugins.shadow.tasks.ConfigureShadowRelocation 2 | buildscript { 3 | dependencies { 4 | classpath ('org.eclipse.jgit:org.eclipse.jgit:') { 5 | version { 6 | strictly '5.13.3.202401111512-r' 7 | } 8 | } 9 | } 10 | } 11 | plugins { 12 | id 'groovy' 13 | id 'maven-publish' 14 | id 'java-gradle-plugin' 15 | id "com.gradle.plugin-publish" version "0.14.0" 16 | id "com.github.johnrengelman.shadow" version "7.0.0" 17 | id "com.gorylenko.gradle-git-properties" version "2.3.2" 18 | } 19 | 20 | buildScan { 21 | termsOfServiceUrl = 'https://gradle.com/terms-of-service' 22 | termsOfServiceAgree = 'yes' 23 | } 24 | 25 | apply plugin: "com.gradle.plugin-publish" 26 | 27 | repositories { 28 | mavenCentral() 29 | maven { 30 | name = 'ajoberstar-backup' 31 | url = 'https://ajoberstar.org/bintray-backup/' 32 | } 33 | // for debugging 34 | //maven { 35 | // url 'https://repo.gradle.org/gradle/libs-releases-local/' 36 | //} 37 | } 38 | 39 | def integrationTest = sourceSets.create("integrationTest") 40 | 41 | dependencies { 42 | shadow gradleApi() 43 | shadow localGroovy() 44 | implementation('org.ajoberstar.grgit:grgit-core:4.1.1') { 45 | exclude(group: 'org.slf4j') 46 | } 47 | // for debugging 48 | //implementation 'org.gradle:gradle-language-jvm:5.6.2' 49 | //implementation 'org.gradle:gradle-language-java:5.6.2' 50 | 51 | 52 | testImplementation 'junit:junit:4.12' 53 | testImplementation gradleTestKit() 54 | 55 | integrationTestImplementation 'junit:junit:4.12' 56 | integrationTestImplementation gradleTestKit() 57 | integrationTestImplementation project 58 | integrationTestImplementation sourceSets.test.output // Include test files for git project utils 59 | } 60 | 61 | task relocateShadowJar(type: ConfigureShadowRelocation) { 62 | target = tasks.shadowJar 63 | prefix = "gradlegitproperties" 64 | } 65 | 66 | tasks.shadowJar.dependsOn tasks.relocateShadowJar 67 | 68 | shadowJar { 69 | archiveClassifier.set('') 70 | } 71 | 72 | tasks.shadowJar.dependsOn tasks.jar 73 | 74 | components.java.withVariantsFromConfiguration(configurations.runtimeElements) { 75 | skip() 76 | } 77 | 78 | version = "2.5.0" 79 | group = "com.gorylenko.gradle-git-properties" 80 | 81 | gitProperties { 82 | keys = ['git.branch','git.commit.id','git.commit.time'] 83 | dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ" 84 | dateFormatTimeZone = "PST" 85 | } 86 | 87 | tasks.withType(GroovyCompile) { 88 | targetCompatibility = JavaVersion.VERSION_1_8 89 | } 90 | test { 91 | testLogging { 92 | events "passed", "skipped", "failed" 93 | exceptionFormat "full" 94 | } 95 | } 96 | 97 | tasks.register("integrationTest", Test) { 98 | dependsOn tasks.shadowJar 99 | 100 | description = 'Runs the integration tests.' 101 | group = "verification" 102 | testClassesDirs = integrationTest.output.classesDirs 103 | classpath = integrationTest.runtimeClasspath 104 | it.systemProperty "integration.plugin.path", tasks.shadowJar.outputs.getFiles().asPath // Pass java system property indicating integration plugin path 105 | } 106 | 107 | tasks.register("sourceJar", Jar) { 108 | classifier = "sources" 109 | from sourceSets.main.resources, sourceSets.main.groovy 110 | 111 | dependsOn tasks.named("classes") 112 | } 113 | 114 | publishing { 115 | 116 | publications { 117 | 118 | pluginJar(MavenPublication) { publication -> 119 | 120 | from project.shadow.component(publication) 121 | 122 | artifact sourceJar 123 | } 124 | } 125 | // for testing: ./gradlew clean publishToMavenLocal 126 | repositories { 127 | mavenLocal() 128 | } 129 | } 130 | 131 | pluginBundle { 132 | website = 'http://github.com/n0mer/gradle-git-properties' 133 | vcsUrl = 'https://github.com/n0mer/gradle-git-properties' 134 | description = 'Produce git.properties for spring-boot-actuator' 135 | tags = ['git', 'spring-boot'] 136 | 137 | plugins { 138 | gitPropertiesPlugin { 139 | id = 'com.gorylenko.gradle-git-properties' 140 | displayName = 'Gradle Git Properties plugin' 141 | } 142 | } 143 | } 144 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/n0mer/gradle-git-properties/d818a2765238cb52109d32851dad311139da62ed/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.0-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | # 4 | # Copyright 2015 the original author or authors. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # https://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | ############################################################################## 20 | ## 21 | ## Gradle start up script for UN*X 22 | ## 23 | ############################################################################## 24 | 25 | # Attempt to set APP_HOME 26 | # Resolve links: $0 may be a link 27 | PRG="$0" 28 | # Need this for relative symlinks. 29 | while [ -h "$PRG" ] ; do 30 | ls=`ls -ld "$PRG"` 31 | link=`expr "$ls" : '.*-> \(.*\)$'` 32 | if expr "$link" : '/.*' > /dev/null; then 33 | PRG="$link" 34 | else 35 | PRG=`dirname "$PRG"`"/$link" 36 | fi 37 | done 38 | SAVED="`pwd`" 39 | cd "`dirname \"$PRG\"`/" >/dev/null 40 | APP_HOME="`pwd -P`" 41 | cd "$SAVED" >/dev/null 42 | 43 | APP_NAME="Gradle" 44 | APP_BASE_NAME=`basename "$0"` 45 | 46 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 47 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' 48 | 49 | # Use the maximum available, or set MAX_FD != -1 to use that value. 50 | MAX_FD="maximum" 51 | 52 | warn () { 53 | echo "$*" 54 | } 55 | 56 | die () { 57 | echo 58 | echo "$*" 59 | echo 60 | exit 1 61 | } 62 | 63 | # OS specific support (must be 'true' or 'false'). 64 | cygwin=false 65 | msys=false 66 | darwin=false 67 | nonstop=false 68 | case "`uname`" in 69 | CYGWIN* ) 70 | cygwin=true 71 | ;; 72 | Darwin* ) 73 | darwin=true 74 | ;; 75 | MINGW* ) 76 | msys=true 77 | ;; 78 | NONSTOP* ) 79 | nonstop=true 80 | ;; 81 | esac 82 | 83 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 84 | 85 | 86 | # Determine the Java command to use to start the JVM. 87 | if [ -n "$JAVA_HOME" ] ; then 88 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 89 | # IBM's JDK on AIX uses strange locations for the executables 90 | JAVACMD="$JAVA_HOME/jre/sh/java" 91 | else 92 | JAVACMD="$JAVA_HOME/bin/java" 93 | fi 94 | if [ ! -x "$JAVACMD" ] ; then 95 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 96 | 97 | Please set the JAVA_HOME variable in your environment to match the 98 | location of your Java installation." 99 | fi 100 | else 101 | JAVACMD="java" 102 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 103 | 104 | Please set the JAVA_HOME variable in your environment to match the 105 | location of your Java installation." 106 | fi 107 | 108 | # Increase the maximum file descriptors if we can. 109 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 110 | MAX_FD_LIMIT=`ulimit -H -n` 111 | if [ $? -eq 0 ] ; then 112 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 113 | MAX_FD="$MAX_FD_LIMIT" 114 | fi 115 | ulimit -n $MAX_FD 116 | if [ $? -ne 0 ] ; then 117 | warn "Could not set maximum file descriptor limit: $MAX_FD" 118 | fi 119 | else 120 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 121 | fi 122 | fi 123 | 124 | # For Darwin, add options to specify how the application appears in the dock 125 | if $darwin; then 126 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 127 | fi 128 | 129 | # For Cygwin or MSYS, switch paths to Windows format before running java 130 | if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then 131 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 132 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 133 | 134 | JAVACMD=`cygpath --unix "$JAVACMD"` 135 | 136 | # We build the pattern for arguments to be converted via cygpath 137 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 138 | SEP="" 139 | for dir in $ROOTDIRSRAW ; do 140 | ROOTDIRS="$ROOTDIRS$SEP$dir" 141 | SEP="|" 142 | done 143 | OURCYGPATTERN="(^($ROOTDIRS))" 144 | # Add a user-defined pattern to the cygpath arguments 145 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 146 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 147 | fi 148 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 149 | i=0 150 | for arg in "$@" ; do 151 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 152 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 153 | 154 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 155 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 156 | else 157 | eval `echo args$i`="\"$arg\"" 158 | fi 159 | i=`expr $i + 1` 160 | done 161 | case $i in 162 | 0) set -- ;; 163 | 1) set -- "$args0" ;; 164 | 2) set -- "$args0" "$args1" ;; 165 | 3) set -- "$args0" "$args1" "$args2" ;; 166 | 4) set -- "$args0" "$args1" "$args2" "$args3" ;; 167 | 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 168 | 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 169 | 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 170 | 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 171 | 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 172 | esac 173 | fi 174 | 175 | # Escape application args 176 | save () { 177 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 178 | echo " " 179 | } 180 | APP_ARGS=`save "$@"` 181 | 182 | # Collect all arguments for the java command, following the shell quoting and substitution rules 183 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 184 | 185 | exec "$JAVACMD" "$@" 186 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 34 | 35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 37 | 38 | @rem Find java.exe 39 | if defined JAVA_HOME goto findJavaFromJavaHome 40 | 41 | set JAVA_EXE=java.exe 42 | %JAVA_EXE% -version >NUL 2>&1 43 | if "%ERRORLEVEL%" == "0" goto execute 44 | 45 | echo. 46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 47 | echo. 48 | echo Please set the JAVA_HOME variable in your environment to match the 49 | echo location of your Java installation. 50 | 51 | goto fail 52 | 53 | :findJavaFromJavaHome 54 | set JAVA_HOME=%JAVA_HOME:"=% 55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 56 | 57 | if exist "%JAVA_EXE%" goto execute 58 | 59 | echo. 60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 61 | echo. 62 | echo Please set the JAVA_HOME variable in your environment to match the 63 | echo location of your Java installation. 64 | 65 | goto fail 66 | 67 | :execute 68 | @rem Setup the command line 69 | 70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 71 | 72 | 73 | @rem Execute Gradle 74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 75 | 76 | :end 77 | @rem End local scope for the variables with windows NT shell 78 | if "%ERRORLEVEL%"=="0" goto mainEnd 79 | 80 | :fail 81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 82 | rem the _cmd.exe /c_ return code! 83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 84 | exit /b 1 85 | 86 | :mainEnd 87 | if "%OS%"=="Windows_NT" endlocal 88 | 89 | :omega 90 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "com.gradle.enterprise" version "3.6.1" 3 | } 4 | -------------------------------------------------------------------------------- /src/integrationTest/groovy/com/gorylenko/SLF4JBindingPostShadowTest.groovy: -------------------------------------------------------------------------------- 1 | package com.gorylenko 2 | 3 | import com.gorylenko.properties.GitRepositoryBuilder 4 | import org.gradle.testkit.runner.GradleRunner 5 | import org.gradle.testkit.runner.TaskOutcome 6 | import org.junit.Assert 7 | import org.junit.Rule 8 | import org.junit.Test 9 | import org.junit.rules.TemporaryFolder 10 | 11 | class SLF4JBindingPostShadowTest { 12 | @Rule 13 | public final TemporaryFolder temporaryFolder = new TemporaryFolder() 14 | 15 | @Test 16 | void testSFL4JBindingPostShadow() { 17 | def projectDir = temporaryFolder.newFolder() 18 | 19 | def integrationPluginPath = System.properties.get("integration.plugin.path") // Fetch integration jar from shadowJar output 20 | Assert.assertNotNull("integration.plugin.path was null", integrationPluginPath) 21 | 22 | GitRepositoryBuilder.setupProjectDir(projectDir, { gitRepoBuilder -> 23 | // commit 1 new file "hello.txt" 24 | gitRepoBuilder.commitFile("hello.txt", "Hello", "Added hello.txt") 25 | }) 26 | 27 | new File(projectDir, "settings.gradle") << "" 28 | new File(projectDir, "build.gradle") << """ 29 | plugins { 30 | id('com.gorylenko.gradle-git-properties') 31 | } 32 | """.stripIndent() 33 | 34 | def runner = GradleRunner.create() 35 | .withPluginClasspath(Arrays.asList(new File(integrationPluginPath as String))) // Use integration plugin jar 36 | .withArguments("generateGitProperties") 37 | .withProjectDir(projectDir) 38 | 39 | def result = runner.build() 40 | 41 | Assert.assertEquals(TaskOutcome.SUCCESS, result.task(":generateGitProperties").outcome) 42 | Assert.assertFalse("Project improperly shadowed slf4j-api!", result.output.contains("org.slf4j.impl.StaticLoggerBinder")) 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /src/main/groovy/com/gorylenko/GenerateGitPropertiesTask.groovy: -------------------------------------------------------------------------------- 1 | package com.gorylenko 2 | 3 | import org.gradle.api.DefaultTask 4 | import org.gradle.api.GradleException 5 | import org.gradle.api.Transformer 6 | import org.gradle.api.file.Directory 7 | import org.gradle.api.file.FileTree 8 | import org.gradle.api.file.ProjectLayout 9 | import org.gradle.api.file.RegularFileProperty 10 | import org.gradle.api.model.ObjectFactory 11 | import org.gradle.api.provider.Property 12 | import org.gradle.api.tasks.CacheableTask 13 | import org.gradle.api.tasks.Input 14 | import org.gradle.api.tasks.InputFiles 15 | import org.gradle.api.tasks.Internal 16 | import org.gradle.api.tasks.OutputFile 17 | import org.gradle.api.tasks.PathSensitive 18 | import org.gradle.api.tasks.PathSensitivity 19 | import org.gradle.api.tasks.TaskAction 20 | 21 | import javax.inject.Inject 22 | 23 | @CacheableTask 24 | public class GenerateGitPropertiesTask extends DefaultTask { 25 | public static final String TASK_NAME = "generateGitProperties" 26 | 27 | private static final String DEFAULT_OUTPUT_DIR = "resources/main" 28 | 29 | private final GitPropertiesPluginExtension gitProperties 30 | 31 | private final FileTree source 32 | private final Property projectVersion 33 | 34 | GenerateGitPropertiesTask() { 35 | // Description for the task 36 | description = 'Generate a git.properties file.' 37 | 38 | this.gitProperties = project.extensions.getByType(GitPropertiesPluginExtension) 39 | 40 | // we will not be able to access the project in the @TaskAction method, 41 | // if the configuration cache is enabled 42 | this.source = project.fileTree(gitProperties.dotGitDirectory) { 43 | include('config') 44 | include('HEAD') 45 | include('refs/**') 46 | } 47 | this.projectVersion = project.objects.property(Object).convention(project.version) 48 | 49 | outputs.upToDateWhen { GenerateGitPropertiesTask task -> 50 | // when extProperty is configured or failOnNoGitDirectory=false always execute the task 51 | return !task.gitProperties.extProperty && task.gitProperties.failOnNoGitDirectory 52 | } 53 | } 54 | 55 | @Inject 56 | ObjectFactory getObjectFactory() { 57 | throw new UnsupportedOperationException() 58 | } 59 | 60 | @Inject 61 | ProjectLayout getLayout() { 62 | throw new UnsupportedOperationException() 63 | } 64 | 65 | @InputFiles 66 | @PathSensitive(PathSensitivity.RELATIVE) 67 | public FileTree getSource() { 68 | return source 69 | } 70 | 71 | @OutputFile 72 | public RegularFileProperty getOutput() { 73 | return getGitPropertiesFile() 74 | } 75 | 76 | @Input 77 | public Property getProjectVersion() { 78 | return projectVersion 79 | } 80 | 81 | private Map generateProperties() { 82 | if (logger.debugEnabled) { 83 | logger.debug("gitProperties = ${gitProperties}") 84 | } 85 | 86 | File dotGitDirectory = gitProperties.dotGitDirectory.get().asFile 87 | logger.info("dotGitDirectory = [${dotGitDirectory?.absolutePath}]") 88 | 89 | // Generate properties 90 | 91 | GitProperties builder = new GitProperties() 92 | Map newMap = builder.generate(dotGitDirectory, 93 | gitProperties.keys, gitProperties.dateFormat, gitProperties.dateFormatTimeZone, gitProperties.branch, 94 | projectVersion.get(), gitProperties.customProperties) 95 | 96 | if (logger.debugEnabled) { 97 | logger.debug("Generated Git properties = ${newMap}") 98 | } 99 | 100 | return newMap 101 | } 102 | 103 | @Internal 104 | GitPropertiesPluginExtension getGitProperties() { 105 | return gitProperties 106 | } 107 | 108 | @TaskAction 109 | void generate() { 110 | 111 | if (getSource().empty) { 112 | if (gitProperties.failOnNoGitDirectory) { 113 | throw new GradleException( 114 | "No Git repository found. " + 115 | "Ensure the gitProperties.dotGitDirectory property points to the correct .git directory.") 116 | } else { 117 | logger.info("No Git repository found and failOnNoGitDirectory = false.") 118 | return 119 | } 120 | } 121 | 122 | Map newMap = generateProperties() 123 | 124 | // Expose generated properties to project.ext[gitProperties.extProperty] if configured 125 | if (gitProperties.extProperty) { 126 | logger.debug("Exposing git properties model to project.ext[${gitProperties.extProperty}]") 127 | project.ext[gitProperties.extProperty] = new HashMap(newMap) 128 | } 129 | 130 | // Write to git.properties file 131 | logger.debug("gitProperties.gitPropertiesResourceDir=${gitProperties.gitPropertiesResourceDir}") 132 | logger.debug("gitProperties.gitPropertiesDir=${gitProperties.gitPropertiesDir}") 133 | logger.debug("gitProperties.gitPropertiesName=${gitProperties.gitPropertiesName}") 134 | 135 | RegularFileProperty file = getGitPropertiesFile() 136 | def absolutePath = file.asFile.map(new Transformer() { 137 | @Override 138 | String transform(File f) { 139 | f.absolutePath 140 | } 141 | }).getOrElse("unknown") 142 | logger.info "git.properties location = [${absolutePath}]" 143 | 144 | boolean written = new PropertiesFileWriter().write(newMap, file.asFile.get(), gitProperties.force) 145 | if (written) { 146 | logger.info("Written properties to [${file}]...") 147 | } else { 148 | logger.info("Skip writing properties to [${file}] as it is up-to-date.") 149 | } 150 | } 151 | 152 | private Directory getGitPropertiesDir() { 153 | if (gitProperties.gitPropertiesResourceDir.present) { 154 | return gitProperties.gitPropertiesResourceDir.get() 155 | } else if (gitProperties.gitPropertiesDir.present) { 156 | return gitProperties.gitPropertiesDir.get() 157 | } else { 158 | return layout.buildDirectory.dir(DEFAULT_OUTPUT_DIR).get() 159 | } 160 | } 161 | 162 | private RegularFileProperty getGitPropertiesFile() { 163 | def fileProperty = objectFactory.fileProperty() 164 | fileProperty.set(getGitPropertiesDir().file(gitProperties.gitPropertiesName)) 165 | return fileProperty 166 | } 167 | } 168 | -------------------------------------------------------------------------------- /src/main/groovy/com/gorylenko/GitProperties.groovy: -------------------------------------------------------------------------------- 1 | package com.gorylenko 2 | 3 | import com.gorylenko.properties.CacheSupport 4 | 5 | import java.text.SimpleDateFormat 6 | 7 | import org.ajoberstar.grgit.Grgit 8 | 9 | import com.gorylenko.properties.BranchProperty 10 | import com.gorylenko.properties.BuildHostProperty 11 | import com.gorylenko.properties.BuildUserEmailProperty 12 | import com.gorylenko.properties.BuildUserNameProperty 13 | import com.gorylenko.properties.BuildVersionProperty 14 | import com.gorylenko.properties.ClosestTagCommitCountProperty 15 | import com.gorylenko.properties.ClosestTagNameProperty 16 | import com.gorylenko.properties.CommitIdAbbrevProperty 17 | import com.gorylenko.properties.CommitIdDescribeProperty 18 | import com.gorylenko.properties.CommitIdProperty 19 | import com.gorylenko.properties.CommitMessageFullProperty 20 | import com.gorylenko.properties.CommitMessageShortProperty 21 | import com.gorylenko.properties.CommitTimeProperty 22 | import com.gorylenko.properties.CommitUserEmailProperty 23 | import com.gorylenko.properties.CommitUserNameProperty 24 | import com.gorylenko.properties.DirtyProperty 25 | import com.gorylenko.properties.RemoteOriginUrlProperty 26 | import com.gorylenko.properties.TagsProperty 27 | import com.gorylenko.properties.TotalCommitCountProperty 28 | 29 | import java.io.File 30 | import java.util.List 31 | import java.util.Map 32 | 33 | 34 | class GitProperties { 35 | 36 | private static final String KEY_GIT_BRANCH = "git.branch" 37 | private static final String KEY_GIT_COMMIT_ID = "git.commit.id" 38 | private static final String KEY_GIT_COMMIT_ID_ABBREVIATED = "git.commit.id.abbrev" 39 | private static final String KEY_GIT_COMMIT_USER_NAME = "git.commit.user.name" 40 | private static final String KEY_GIT_COMMIT_USER_EMAIL = "git.commit.user.email" 41 | private static final String KEY_GIT_COMMIT_SHORT_MESSAGE = "git.commit.message.short" 42 | private static final String KEY_GIT_COMMIT_FULL_MESSAGE = "git.commit.message.full" 43 | private static final String KEY_GIT_COMMIT_TIME = "git.commit.time" 44 | private static final String KEY_GIT_COMMIT_ID_DESCRIBE = "git.commit.id.describe" 45 | private static final String KEY_GIT_REMOTE_ORIGIN_URL = "git.remote.origin.url" 46 | private static final String KEY_GIT_TAGS = "git.tags" 47 | private static final String KEY_GIT_CLOSEST_TAG_NAME = "git.closest.tag.name" 48 | private static final String KEY_GIT_CLOSEST_TAG_COMMIT_COUNT = "git.closest.tag.commit.count" 49 | private static final String KEY_GIT_TOTAL_COMMIT_COUNT = "git.total.commit.count" 50 | private static final String KEY_GIT_DIRTY = "git.dirty" 51 | private static final String KEY_GIT_BUILD_USER_NAME = "git.build.user.name" 52 | private static final String KEY_GIT_BUILD_USER_EMAIL = "git.build.user.email" 53 | private static final String KEY_GIT_BUILD_VERSION = "git.build.version" 54 | private static final String KEY_GIT_BUILD_HOST = "git.build.host" 55 | 56 | public Map generate(File dotGitDirectory, List keys, String dateFormat, String dateFormatTimeZone, String branch, 57 | Object buildVersion, Map customProperties) { 58 | 59 | // Find standard properties and custom properties to be generated 60 | 61 | Map properties = getStandardPropertiesMap(dateFormat, dateFormatTimeZone, branch, buildVersion).subMap(keys) 62 | if (customProperties) { 63 | properties.putAll(customProperties) 64 | } 65 | 66 | // Evaluate property values 67 | 68 | def result = [:] 69 | def repo = Grgit.open(dir: dotGitDirectory) 70 | try { 71 | properties.each{ k, v -> result.put(k, v instanceof Closure ? v.call(repo).toString() : v.toString() ) } 72 | } finally { 73 | repo.close() 74 | } 75 | 76 | return result 77 | } 78 | 79 | public static List getStandardProperties() { 80 | return getStandardPropertiesMap(null, null, null, null).keySet() as List 81 | } 82 | 83 | private static Map getStandardPropertiesMap(String dateFormat, String dateFormatTimeZone, String branch, Object buildVersion) { 84 | def cacheSupport = new CacheSupport() 85 | 86 | def map = [(KEY_GIT_BRANCH) : new BranchProperty(branch) 87 | , (KEY_GIT_COMMIT_ID) : new CommitIdProperty() 88 | , (KEY_GIT_COMMIT_ID_ABBREVIATED) : new CommitIdAbbrevProperty() 89 | , (KEY_GIT_COMMIT_USER_NAME) : new CommitUserNameProperty() 90 | , (KEY_GIT_COMMIT_USER_EMAIL) : new CommitUserEmailProperty() 91 | , (KEY_GIT_COMMIT_SHORT_MESSAGE) : new CommitMessageShortProperty() 92 | , (KEY_GIT_COMMIT_FULL_MESSAGE) : new CommitMessageFullProperty() 93 | , (KEY_GIT_COMMIT_TIME) : new CommitTimeProperty(dateFormat, dateFormatTimeZone) 94 | , (KEY_GIT_COMMIT_ID_DESCRIBE) : new CommitIdDescribeProperty() 95 | , (KEY_GIT_REMOTE_ORIGIN_URL) : new RemoteOriginUrlProperty() 96 | , (KEY_GIT_TAGS) : new TagsProperty() 97 | , (KEY_GIT_CLOSEST_TAG_NAME) : new ClosestTagNameProperty(cacheSupport) 98 | , (KEY_GIT_CLOSEST_TAG_COMMIT_COUNT) : new ClosestTagCommitCountProperty(cacheSupport) 99 | , (KEY_GIT_TOTAL_COMMIT_COUNT) : new TotalCommitCountProperty(cacheSupport) 100 | , (KEY_GIT_DIRTY) : new DirtyProperty() 101 | , (KEY_GIT_BUILD_USER_NAME) : new BuildUserNameProperty() 102 | , (KEY_GIT_BUILD_USER_EMAIL) : new BuildUserEmailProperty() 103 | , (KEY_GIT_BUILD_VERSION) : new BuildVersionProperty(buildVersion) 104 | , (KEY_GIT_BUILD_HOST) : new BuildHostProperty()] 105 | 106 | return map 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /src/main/groovy/com/gorylenko/GitPropertiesPlugin.groovy: -------------------------------------------------------------------------------- 1 | package com.gorylenko 2 | 3 | import groovy.transform.ToString 4 | import org.gradle.api.Plugin 5 | import org.gradle.api.Project 6 | import org.gradle.api.file.Directory 7 | import org.gradle.api.file.DirectoryProperty 8 | import org.gradle.api.file.ProjectLayout 9 | import org.gradle.api.plugins.BasePlugin 10 | import org.gradle.api.plugins.JavaPlugin 11 | import org.gradle.api.tasks.InputDirectory 12 | import org.gradle.api.tasks.SourceSet 13 | import org.gradle.api.tasks.SourceSetContainer 14 | 15 | class GitPropertiesPlugin implements Plugin { 16 | 17 | private static final String EXTENSION_NAME = "gitProperties" 18 | private static final String DEFAULT_OUTPUT_DIR = "resources/main" 19 | 20 | @Override 21 | void apply(Project project) { 22 | def extension = project.extensions.create(EXTENSION_NAME, GitPropertiesPluginExtension, project) 23 | def task = project.tasks.register(GenerateGitPropertiesTask.TASK_NAME, GenerateGitPropertiesTask) { 24 | group = BasePlugin.BUILD_GROUP 25 | } 26 | 27 | // if Java plugin is applied, execute this task automatically when "classes" task is executed 28 | // see https://guides.gradle.org/implementing-gradle-plugins/#reacting_to_plugins 29 | project.plugins.withType(JavaPlugin) { 30 | project.tasks.named(JavaPlugin.CLASSES_TASK_NAME).configure { 31 | dependsOn(task) 32 | 33 | // if Java plugin is used, this method will be called to register gitPropertiesResourceDir to classpath 34 | // at the end of evaluation phase (to make sure extension values are set) 35 | if (extension.gitPropertiesResourceDir.present) { 36 | String gitPropertiesDir = getGitPropertiesDir(extension, project.layout).asFile.absolutePath 37 | def sourceSets = project.extensions.getByType(SourceSetContainer) 38 | sourceSets.named(SourceSet.MAIN_SOURCE_SET_NAME).configure { 39 | it.resources.srcDir(gitPropertiesDir) 40 | } 41 | } 42 | } 43 | } 44 | } 45 | 46 | private static Directory getGitPropertiesDir(GitPropertiesPluginExtension extension, ProjectLayout layout) { 47 | if (extension.gitPropertiesResourceDir.present) { 48 | return extension.gitPropertiesResourceDir.get() 49 | } else if (extension.gitPropertiesDir.present) { 50 | return extension.gitPropertiesDir.get() 51 | } else { 52 | return layout.buildDirectory.dir(DEFAULT_OUTPUT_DIR).get() 53 | } 54 | } 55 | } 56 | 57 | @ToString(includeNames=true) 58 | class GitPropertiesPluginExtension { 59 | final DirectoryProperty gitPropertiesDir 60 | final DirectoryProperty gitPropertiesResourceDir 61 | String gitPropertiesName = "git.properties" 62 | final DirectoryProperty dotGitDirectory 63 | List keys = GitProperties.standardProperties 64 | Map customProperties = [:] 65 | String dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ" 66 | String dateFormatTimeZone 67 | String branch 68 | String extProperty 69 | boolean failOnNoGitDirectory = true 70 | boolean force 71 | 72 | GitPropertiesPluginExtension(Project project) { 73 | gitPropertiesDir = project.objects.directoryProperty() 74 | gitPropertiesResourceDir = project.objects.directoryProperty() 75 | dotGitDirectory = project.objects.directoryProperty().convention(project.layout.projectDirectory.dir(".git")) 76 | } 77 | 78 | void customProperty(String name, Object value) { 79 | customProperties.put(name, value) 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/main/groovy/com/gorylenko/PropertiesFileWriter.groovy: -------------------------------------------------------------------------------- 1 | package com.gorylenko 2 | 3 | import com.gorylenko.writer.NormalizeEOLOutputStream 4 | import com.gorylenko.writer.SkipPropertiesCommentsOutputStream 5 | 6 | class PropertiesFileWriter { 7 | 8 | boolean write(Map properties, File file, boolean force) { 9 | if (!force && hasSameContent(file, properties)) { 10 | // Skipping writing [${file}] as it is up-to-date. 11 | return false 12 | } else { 13 | // Writing to [${file}]... 14 | writeToPropertiesFile(properties, file) 15 | return true 16 | } 17 | } 18 | 19 | private static class SortedProperties extends Properties { 20 | private static final long serialVersionUID = 1L 21 | 22 | @Override 23 | synchronized Enumeration keys() { 24 | Vector v = new Vector(keySet()) 25 | Collections.sort(v) 26 | return new Vector(v).elements() 27 | } 28 | 29 | @Override 30 | Set> entrySet() { 31 | keys().collect { new AbstractMap.SimpleImmutableEntry(it, get(it)) } as LinkedHashSet 32 | } 33 | } 34 | 35 | private void writeToPropertiesFile(Map properties, File propsFile) { 36 | 37 | def props = new SortedProperties() 38 | props.putAll(properties) 39 | 40 | if (!propsFile.parentFile.exists()) { 41 | propsFile.parentFile.mkdirs() 42 | } 43 | if (propsFile.exists()) { 44 | propsFile.delete() 45 | } 46 | propsFile.createNewFile() 47 | 48 | new NormalizeEOLOutputStream(new SkipPropertiesCommentsOutputStream(new FileOutputStream(propsFile))).withStream { os -> 49 | props.store(os, null) 50 | } 51 | } 52 | 53 | private boolean hasSameContent(File propsFile, Map properties) { 54 | boolean sameContent = false 55 | if (propsFile.exists()) { 56 | def props = new Properties() 57 | propsFile.withInputStream { 58 | props.load it 59 | } 60 | if (props.equals(properties)) { 61 | sameContent = true 62 | } 63 | } 64 | return sameContent 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/main/groovy/com/gorylenko/properties/AbstractGitProperty.groovy: -------------------------------------------------------------------------------- 1 | package com.gorylenko.properties 2 | 3 | import org.ajoberstar.grgit.Grgit 4 | 5 | class AbstractGitProperty extends Closure { 6 | 7 | AbstractGitProperty() { 8 | super(null) 9 | } 10 | 11 | boolean isEmpty(Grgit repo) { 12 | return ! repo.repository.jgit.repository.resolve('HEAD') 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/groovy/com/gorylenko/properties/BranchProperty.groovy: -------------------------------------------------------------------------------- 1 | package com.gorylenko.properties 2 | 3 | import org.ajoberstar.grgit.Grgit 4 | 5 | class BranchProperty extends AbstractGitProperty { 6 | String branch 7 | Map env 8 | 9 | def branchEnvs = [ 10 | 11 | 'JOB_NAME' : ['GIT_LOCAL_BRANCH', 'GIT_BRANCH', 'BRANCH_NAME'], // jenkins/hudson 12 | 13 | 'TRAVIS' : ['TRAVIS_BRANCH'], // TravisCI https://docs.travis-ci.com/user/environment-variables/#default-environment-variables 14 | 15 | 'TEAMCITY_VERSION' : ['teamcity.build.branch'], // https://confluence.jetbrains.com/display/TCD9/Predefined+Build+Parameters 16 | 17 | 'GITLAB_CI' : ['CI_COMMIT_REF_NAME'], // https://docs.gitlab.com/ee/ci/variables/#predefined-variables-environment-variables 18 | 19 | 'BAMBOO_BUILDKEY' : ['BAMBOO_PLANREPOSITORY_BRANCH'] //https://confluence.atlassian.com/bamboo/bamboo-variables-289277087.html 20 | 21 | ] 22 | BranchProperty(String branch) { 23 | this.branch = branch 24 | } 25 | 26 | String doCall(Grgit repo) { 27 | 28 | String branchName 29 | 30 | // if user didn't provide a branch name, try to detect using environment variables 31 | if (this.branch == null) { 32 | 33 | branchName = null 34 | Map env = getEnv() 35 | outer: for ( e in branchEnvs ) { 36 | if (env.containsKey(e.key)) { 37 | for (String name in e.value) { 38 | if (env.containsKey(name)) { 39 | branchName = env[name] 40 | break outer 41 | } 42 | } 43 | } 44 | } 45 | 46 | // could not detect from env variables, use branch from repo 47 | if (!branchName && !isEmpty(repo)) { 48 | branchName = repo.branch.current().name 49 | } 50 | 51 | } else { 52 | // user provided a branch value, use it 53 | branchName = this.branch 54 | } 55 | 56 | return branchName ?: '' 57 | } 58 | 59 | Map getEnv() { 60 | return env != null ? env : System.getenv() 61 | } 62 | 63 | void setEnv(env) { 64 | this.env = env 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/main/groovy/com/gorylenko/properties/BuildHostProperty.groovy: -------------------------------------------------------------------------------- 1 | package com.gorylenko.properties 2 | 3 | import java.net.InetAddress 4 | import java.net.UnknownHostException 5 | 6 | import org.ajoberstar.grgit.Grgit 7 | 8 | class BuildHostProperty extends Closure { 9 | 10 | BuildHostProperty() { 11 | super(null) 12 | } 13 | 14 | String doCall(Grgit repo) { 15 | String buildHost = null 16 | try { 17 | buildHost = InetAddress.localHost.hostName 18 | } catch (Exception e) { 19 | } 20 | return buildHost ?: '' 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/groovy/com/gorylenko/properties/BuildUserEmailProperty.groovy: -------------------------------------------------------------------------------- 1 | package com.gorylenko.properties 2 | 3 | import org.ajoberstar.grgit.Grgit 4 | 5 | class BuildUserEmailProperty extends Closure { 6 | 7 | BuildUserEmailProperty() { 8 | super(null) 9 | } 10 | 11 | String doCall(Grgit repo) { 12 | String email = repo.repository.jgit.repository.config.getString("user", null, "email") 13 | return email ?: '' 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/main/groovy/com/gorylenko/properties/BuildUserNameProperty.groovy: -------------------------------------------------------------------------------- 1 | package com.gorylenko.properties 2 | 3 | import org.ajoberstar.grgit.Grgit 4 | 5 | class BuildUserNameProperty extends Closure { 6 | 7 | BuildUserNameProperty() { 8 | super(null) 9 | } 10 | 11 | String doCall(Grgit repo) { 12 | String username = repo.repository.jgit.repository.config.getString("user", null, "name") 13 | return username ?: '' 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/main/groovy/com/gorylenko/properties/BuildVersionProperty.groovy: -------------------------------------------------------------------------------- 1 | package com.gorylenko.properties 2 | 3 | import org.ajoberstar.grgit.Grgit 4 | 5 | class BuildVersionProperty extends Closure { 6 | Object version 7 | BuildVersionProperty(Object version) { 8 | super(null) 9 | this.version = version 10 | } 11 | 12 | String doCall(Grgit repo) { 13 | return "$version" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/main/groovy/com/gorylenko/properties/CacheSupport.groovy: -------------------------------------------------------------------------------- 1 | package com.gorylenko.properties 2 | 3 | import groovy.transform.Memoized 4 | import org.ajoberstar.grgit.Grgit 5 | import org.eclipse.jgit.lib.Constants 6 | import org.eclipse.jgit.lib.ObjectId 7 | 8 | import java.util.concurrent.ConcurrentHashMap 9 | 10 | class CacheSupport { 11 | 12 | private static final Map cache = new ConcurrentHashMap() 13 | 14 | Object get(Object key) { 15 | return cache.get(key) 16 | } 17 | 18 | void put(Object key, Object value) { 19 | cache.put(key, value) 20 | } 21 | 22 | @Memoized 23 | String describe(Grgit repo, boolean longDescr) { 24 | return repo.describe(longDescr: longDescr) 25 | } 26 | 27 | Integer totalCommitCount(Grgit repo) { 28 | ObjectId headId = repo.repository.jgit.repository.resolve(Constants.HEAD) 29 | if (get(headId) == null) { 30 | Iterable commits = repo.repository.jgit.log().call() 31 | int count = 0 32 | for( Object commit : commits ) { 33 | count++ 34 | } 35 | put(headId, count) 36 | } 37 | return get(headId) 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/groovy/com/gorylenko/properties/ClosestTagCommitCountProperty.groovy: -------------------------------------------------------------------------------- 1 | package com.gorylenko.properties 2 | 3 | import org.ajoberstar.grgit.Grgit 4 | 5 | class ClosestTagCommitCountProperty extends AbstractGitProperty { 6 | CacheSupport cacheSupport 7 | ClosestTagCommitCountProperty(CacheSupport cacheSupport) { 8 | this.cacheSupport = cacheSupport 9 | } 10 | 11 | String doCall(Grgit repo) { 12 | return isEmpty(repo) ? '' : closestTagCommitCount(repo) 13 | } 14 | 15 | String closestTagCommitCount(Grgit repo) { 16 | try { 17 | 18 | String describe = this.cacheSupport.describe(repo, true) 19 | if (describe) { 20 | // remove commit ID 21 | describe = describe.substring(0, describe.lastIndexOf('-')) 22 | describe = describe.substring(describe.lastIndexOf('-') + 1) 23 | } 24 | return describe ?: '' 25 | 26 | } catch (org.eclipse.jgit.api.errors.JGitInternalException e) { 27 | if (isShallowClone(repo)) { 28 | // shallow clone, use value "" 29 | return '' 30 | } else { 31 | throw e; 32 | } 33 | } 34 | } 35 | boolean isShallowClone(Grgit repo) { 36 | File shallow = new File(repo.repository.rootDir, ".git/shallow") 37 | return shallow.exists() 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/groovy/com/gorylenko/properties/ClosestTagNameProperty.groovy: -------------------------------------------------------------------------------- 1 | package com.gorylenko.properties 2 | 3 | import org.ajoberstar.grgit.Grgit 4 | 5 | class ClosestTagNameProperty extends AbstractGitProperty { 6 | CacheSupport cacheSupport 7 | ClosestTagNameProperty(CacheSupport cacheSupport) { 8 | this.cacheSupport = cacheSupport 9 | } 10 | 11 | String doCall(Grgit repo) { 12 | return isEmpty(repo) ? '' : closestTagName(repo) 13 | } 14 | 15 | String closestTagName(Grgit repo) { 16 | try { 17 | 18 | String describe = this.cacheSupport.describe(repo, true) 19 | if (describe) { 20 | // remove commit ID 21 | describe = describe.substring(0, describe.lastIndexOf('-')) 22 | // remove commit number 23 | describe = describe.substring(0, describe.lastIndexOf('-')) 24 | } 25 | return describe ?: '' 26 | 27 | } catch (org.eclipse.jgit.api.errors.JGitInternalException e) { 28 | if (isShallowClone(repo)) { 29 | // shallow clone, use value "" 30 | return '' 31 | } else { 32 | throw e; 33 | } 34 | } 35 | } 36 | 37 | boolean isShallowClone(Grgit repo) { 38 | File shallow = new File(repo.repository.rootDir, ".git/shallow") 39 | return shallow.exists() 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/groovy/com/gorylenko/properties/CommitIdAbbrevProperty.groovy: -------------------------------------------------------------------------------- 1 | package com.gorylenko.properties 2 | 3 | import org.ajoberstar.grgit.Grgit 4 | 5 | class CommitIdAbbrevProperty extends AbstractGitProperty { 6 | 7 | String doCall(Grgit repo) { 8 | return isEmpty(repo) ? '' : repo.head().abbreviatedId 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/main/groovy/com/gorylenko/properties/CommitIdDescribeProperty.groovy: -------------------------------------------------------------------------------- 1 | package com.gorylenko.properties 2 | 3 | import org.ajoberstar.grgit.Grgit 4 | 5 | class CommitIdDescribeProperty extends AbstractGitProperty { 6 | 7 | String doCall(Grgit repo) { 8 | return isEmpty(repo) ? '' : commitIdDescribe(repo, '-dirty') 9 | } 10 | 11 | private String commitIdDescribe(Grgit repo, String dirtyMark) { 12 | 13 | String describe 14 | try { 15 | describe = repo.describe() 16 | if (describe == null && isShallowClone(repo)) { 17 | // jgit 5 will return null while jgit 4 will throw exception on shallow clone 18 | // shallow clone, use the fallback value "" 19 | describe = repo.head().abbreviatedId 20 | } 21 | } catch (org.eclipse.jgit.api.errors.JGitInternalException e) { 22 | if (isShallowClone(repo)) { 23 | // shallow clone, use the fallback value "" 24 | describe = repo.head().abbreviatedId 25 | } else { 26 | throw e; 27 | } 28 | } 29 | 30 | if (describe && !repo.status().clean) { 31 | describe += dirtyMark 32 | } 33 | return describe ?: '' 34 | } 35 | 36 | boolean isShallowClone(Grgit repo) { 37 | File shallow = new File(repo.repository.rootDir, ".git/shallow") 38 | return shallow.exists() 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /src/main/groovy/com/gorylenko/properties/CommitIdProperty.groovy: -------------------------------------------------------------------------------- 1 | package com.gorylenko.properties 2 | 3 | import org.ajoberstar.grgit.Grgit 4 | 5 | class CommitIdProperty extends AbstractGitProperty { 6 | 7 | String doCall(Grgit repo) { 8 | return isEmpty(repo) ? '' : repo.head().id 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/main/groovy/com/gorylenko/properties/CommitMessageFullProperty.groovy: -------------------------------------------------------------------------------- 1 | package com.gorylenko.properties 2 | 3 | import org.ajoberstar.grgit.Grgit 4 | 5 | class CommitMessageFullProperty extends AbstractGitProperty { 6 | 7 | String doCall(Grgit repo) { 8 | return isEmpty(repo) ? '' : repo.head().fullMessage 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/main/groovy/com/gorylenko/properties/CommitMessageShortProperty.groovy: -------------------------------------------------------------------------------- 1 | package com.gorylenko.properties 2 | 3 | import org.ajoberstar.grgit.Grgit 4 | 5 | class CommitMessageShortProperty extends AbstractGitProperty { 6 | 7 | String doCall(Grgit repo) { 8 | return isEmpty(repo) ? '' : repo.head().shortMessage 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/main/groovy/com/gorylenko/properties/CommitTimeProperty.groovy: -------------------------------------------------------------------------------- 1 | package com.gorylenko.properties 2 | 3 | import java.text.SimpleDateFormat 4 | import java.time.Instant 5 | import org.ajoberstar.grgit.Grgit 6 | 7 | class CommitTimeProperty extends AbstractGitProperty { 8 | private String dateFormat 9 | private String timezone 10 | 11 | CommitTimeProperty(String dateFormat, String timezone) { 12 | this.dateFormat = dateFormat 13 | this.timezone = timezone 14 | } 15 | 16 | String doCall(Grgit repo) { 17 | return isEmpty(repo) ? '' : formatDate(repo.head().dateTime.toInstant(), dateFormat, timezone) 18 | } 19 | 20 | private String formatDate(Instant instant, String dateFormat, String timezone) { 21 | String date 22 | if (dateFormat) { 23 | def sdf = new SimpleDateFormat(dateFormat) 24 | if (timezone) { 25 | sdf.setTimeZone(TimeZone.getTimeZone(timezone)) 26 | } 27 | date = sdf.format(Date.from(instant)) 28 | } else { 29 | date = instant.epochSecond 30 | } 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/main/groovy/com/gorylenko/properties/CommitUserEmailProperty.groovy: -------------------------------------------------------------------------------- 1 | package com.gorylenko.properties 2 | 3 | import org.ajoberstar.grgit.Grgit 4 | 5 | class CommitUserEmailProperty extends AbstractGitProperty { 6 | 7 | String doCall(Grgit repo) { 8 | return isEmpty(repo) ? '' : repo.head().author.email 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/main/groovy/com/gorylenko/properties/CommitUserNameProperty.groovy: -------------------------------------------------------------------------------- 1 | package com.gorylenko.properties 2 | 3 | import org.ajoberstar.grgit.Grgit 4 | 5 | class CommitUserNameProperty extends AbstractGitProperty { 6 | 7 | String doCall(Grgit repo) { 8 | return isEmpty(repo) ? '' : repo.head().author.name 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/main/groovy/com/gorylenko/properties/DirtyProperty.groovy: -------------------------------------------------------------------------------- 1 | package com.gorylenko.properties 2 | 3 | import org.ajoberstar.grgit.Grgit 4 | 5 | class DirtyProperty extends AbstractGitProperty { 6 | 7 | String doCall(Grgit repo) { 8 | return !repo.status().clean 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/main/groovy/com/gorylenko/properties/RemoteOriginUrlProperty.groovy: -------------------------------------------------------------------------------- 1 | package com.gorylenko.properties 2 | 3 | import java.net.URI 4 | import java.net.URISyntaxException 5 | import java.text.SimpleDateFormat 6 | import java.util.Collection 7 | import java.util.regex.Pattern 8 | 9 | import org.ajoberstar.grgit.Commit 10 | import org.ajoberstar.grgit.Grgit 11 | import org.ajoberstar.grgit.Tag 12 | 13 | class RemoteOriginUrlProperty extends AbstractGitProperty { 14 | 15 | String doCall(Grgit repo) { 16 | String url = repo.repository.jgit.repository.config.getString("remote", "origin", "url") 17 | url = removeUserInfo(url) ?: '' 18 | return url 19 | } 20 | private String removeUserInfo(String url) { 21 | String result = url 22 | if (url) { 23 | try { 24 | URL u = new URL(url) 25 | if (u.userInfo) { 26 | // remove user info from url 27 | result = new URL(u.protocol, u.host, u.port, u.file).toString() 28 | } 29 | } catch (Exception e) { 30 | // cannot parse, just skip it 31 | } 32 | } 33 | return result 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/main/groovy/com/gorylenko/properties/TagsProperty.groovy: -------------------------------------------------------------------------------- 1 | package com.gorylenko.properties 2 | 3 | import java.text.SimpleDateFormat 4 | import java.util.Collection 5 | import org.ajoberstar.grgit.Commit 6 | import org.ajoberstar.grgit.Grgit 7 | import org.ajoberstar.grgit.Tag 8 | 9 | class TagsProperty extends AbstractGitProperty { 10 | 11 | String doCall(Grgit repo) { 12 | return isEmpty(repo) ? '' : repo.tag.list().findAll { it.commit == repo.head() }.collect {it.name}.join(',') 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/groovy/com/gorylenko/properties/TotalCommitCountProperty.groovy: -------------------------------------------------------------------------------- 1 | package com.gorylenko.properties 2 | 3 | import org.ajoberstar.grgit.Grgit 4 | 5 | class TotalCommitCountProperty extends AbstractGitProperty { 6 | CacheSupport cacheSupport 7 | TotalCommitCountProperty(CacheSupport cacheSupport) { 8 | this.cacheSupport = cacheSupport 9 | } 10 | 11 | String doCall(Grgit repo) { 12 | return isEmpty(repo) ? '0' : this.cacheSupport.totalCommitCount(repo).toString() 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/groovy/com/gorylenko/writer/SkipPropertiesCommentsOutputStream.groovy: -------------------------------------------------------------------------------- 1 | package com.gorylenko.writer 2 | 3 | /** 4 | * Remove all lines start with # and end with LF (\n) 5 | */ 6 | class SkipPropertiesCommentsOutputStream extends FilterOutputStream { 7 | 8 | private static int START_COMMENT_CHAR1 = '#' 9 | private static int START_COMMENT_CHAR2 = '!' 10 | private static int LINE_END_CHAR = '\n' 11 | 12 | private boolean commentFound = false 13 | private int lastChar = LINE_END_CHAR 14 | 15 | public SkipPropertiesCommentsOutputStream(OutputStream out) { 16 | super(out) 17 | } 18 | 19 | @Override 20 | public void write(int b) throws IOException { 21 | if (!commentFound && (b == START_COMMENT_CHAR1 || b == START_COMMENT_CHAR2) && lastChar == LINE_END_CHAR) { 22 | commentFound = true 23 | } else if (commentFound && b == LINE_END_CHAR) { 24 | commentFound = false 25 | } else if (!commentFound) { 26 | super.write(b) 27 | } 28 | lastChar = b 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/com/gorylenko/writer/NormalizeEOLOutputStream.java: -------------------------------------------------------------------------------- 1 | package com.gorylenko.writer; 2 | 3 | import java.io.FilterOutputStream; 4 | import java.io.IOException; 5 | import java.io.OutputStream; 6 | 7 | /** 8 | * Convert all line endings to LF characters 9 | * 10 | */ 11 | public class NormalizeEOLOutputStream extends FilterOutputStream { 12 | 13 | private int eolCount = 0; 14 | private int prevChar = 0; 15 | 16 | private static final int CR = '\r'; 17 | private static final int LF = '\n'; 18 | 19 | public NormalizeEOLOutputStream(OutputStream out) { 20 | super(out); 21 | } 22 | 23 | @Override 24 | public void write(int b) throws IOException { 25 | if (b == CR || b == LF) { 26 | if (prevChar != CR && prevChar != LF) { 27 | eolCount ++; // first line ending (CR or LF), count 1 28 | prevChar = b; 29 | } else if (prevChar == b) { 30 | eolCount ++; // next line ending char (like LF LF or CR CR), count 1 31 | prevChar = b; 32 | } else { 33 | // second char of a pair (CR LF), ignore and reset prevChar to 0 34 | prevChar = 0; 35 | } 36 | } else { 37 | writeEOLs(); 38 | prevChar = b; 39 | super.write(b); 40 | } 41 | } 42 | 43 | private void writeEOLs() throws IOException { 44 | // write all buffered line endings 45 | while (eolCount > 0) { 46 | out.write(LF); 47 | eolCount --; 48 | } 49 | } 50 | 51 | @Override 52 | public void flush() throws IOException { 53 | writeEOLs(); 54 | prevChar = 0; 55 | super.flush(); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/main/resources/META-INF/gradle-plugins/com.gorylenko.gradle-git-properties.properties: -------------------------------------------------------------------------------- 1 | implementation-class=com.gorylenko.GitPropertiesPlugin -------------------------------------------------------------------------------- /src/test/groovy/com/gorylenko/BackwardCompatibilityFunctionalTest.groovy: -------------------------------------------------------------------------------- 1 | package com.gorylenko 2 | 3 | import com.gorylenko.properties.GitRepositoryBuilder 4 | import org.gradle.testkit.runner.GradleRunner 5 | import org.gradle.testkit.runner.TaskOutcome 6 | import org.junit.Assume 7 | import org.junit.Rule 8 | import org.junit.Test 9 | import org.junit.rules.TemporaryFolder 10 | import org.junit.runner.RunWith 11 | import org.junit.runners.Parameterized 12 | 13 | import static org.junit.Assert.assertEquals 14 | 15 | @RunWith(Parameterized.class) 16 | public class BackwardCompatibilityFunctionalTest { 17 | @Rule 18 | public final TemporaryFolder temporaryFolder = new TemporaryFolder() 19 | 20 | @Parameterized.Parameters(name = "Gradle {0}") 21 | static List data() { 22 | return [ 23 | ["7.0", ["generateGitProperties", "--configuration-cache", "--build-cache"], "17"], 24 | ["6.8.3", ["generateGitProperties", "--configuration-cache", "--build-cache"], "15"], 25 | ["6.7.1", ["generateGitProperties", "--configuration-cache", "--build-cache"], "15"], 26 | ["6.6.1", ["generateGitProperties", "--configuration-cache", "--build-cache"], "15"], 27 | ["6.5.1", ["generateGitProperties"], "15"], 28 | ["6.4.1", ["generateGitProperties"], "15"], 29 | // ["6.3", ["generateGitProperties"], "15"], // StackOverflowError: https://github.com/gradle/gradle/issues/11466 30 | // ["6.2.2", ["generateGitProperties"], "15"], // StackOverflowError: https://github.com/gradle/gradle/issues/11466 31 | // ["6.1.1", ["generateGitProperties"], "15"], // StackOverflowError: https://github.com/gradle/gradle/issues/11466 32 | // ["6.0.1", ["generateGitProperties"], "15"], // StackOverflowError: https://github.com/gradle/gradle/issues/11466 33 | ["5.6.4", ["generateGitProperties"], "12"], 34 | ["5.5.1", ["generateGitProperties"], "12"], 35 | ["5.1", ["generateGitProperties"], "12"], 36 | // ["5.0", ["generateGitProperties"], "12"], // Doesn't support conventions: https://docs.gradle.org/5.1/release-notes.html#specify-a-convention-for-a-property 37 | ]*.toArray() 38 | } 39 | 40 | private final String gradleVersion; 41 | private final List arguments; 42 | private final String maxJavaVersion; 43 | 44 | BackwardCompatibilityFunctionalTest(String gradleVersion, List arguments, String maxJavaVersion) { 45 | this.gradleVersion = gradleVersion 46 | this.arguments = arguments 47 | this.maxJavaVersion = maxJavaVersion 48 | } 49 | 50 | @Test 51 | public void testPluginSupportsConfigurationCache() { 52 | def javaVersion = System.getProperty("java.version", "99"); 53 | Assume.assumeTrue("Skipping test on Java ${javaVersion}", javaVersion <= maxJavaVersion); 54 | 55 | def projectDir = temporaryFolder.newFolder() 56 | 57 | GitRepositoryBuilder.setupProjectDir(projectDir, { gitRepoBuilder -> 58 | // commit 1 new file "hello.txt" 59 | gitRepoBuilder.commitFile("hello.txt", "Hello", "Added hello.txt") 60 | }) 61 | 62 | new File(projectDir, "settings.gradle") << "" 63 | new File(projectDir, "build.gradle") << """ 64 | plugins { 65 | id('java') 66 | id('com.gorylenko.gradle-git-properties') 67 | } 68 | """.stripIndent() 69 | 70 | def runner = GradleRunner.create() 71 | .withGradleVersion(gradleVersion) 72 | .withPluginClasspath() 73 | .withArguments(arguments) 74 | .withProjectDir(projectDir) 75 | 76 | def result = runner.build() 77 | assertEquals(TaskOutcome.SUCCESS, result.task(":generateGitProperties").outcome) 78 | 79 | result = runner.build() 80 | assertEquals(TaskOutcome.UP_TO_DATE, result.task(":generateGitProperties").outcome) 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/test/groovy/com/gorylenko/BasicFunctionalTest.groovy: -------------------------------------------------------------------------------- 1 | package com.gorylenko 2 | 3 | import com.gorylenko.properties.GitRepositoryBuilder 4 | import org.gradle.testkit.runner.GradleRunner 5 | import org.gradle.testkit.runner.TaskOutcome 6 | import org.junit.Rule 7 | import org.junit.Test 8 | import org.junit.rules.TemporaryFolder 9 | 10 | import static org.hamcrest.CoreMatchers.containsString 11 | import static org.junit.Assert.assertEquals 12 | import static org.junit.Assert.assertThat 13 | 14 | public class BasicFunctionalTest { 15 | @Rule 16 | public final TemporaryFolder temporaryFolder = new TemporaryFolder() 17 | 18 | @Test 19 | public void testPluginFailsWithoutGitDirectory() { 20 | def projectDir = temporaryFolder.newFolder() 21 | new File(projectDir, "settings.gradle") << "" 22 | new File(projectDir, "build.gradle") << """ 23 | plugins { 24 | id('com.gorylenko.gradle-git-properties') 25 | } 26 | """.stripIndent() 27 | 28 | def runner = GradleRunner.create() 29 | .withPluginClasspath() 30 | .withArguments("generateGitProperties") 31 | .withProjectDir(projectDir) 32 | 33 | def result = runner.buildAndFail() 34 | 35 | assertEquals(TaskOutcome.FAILED, result.task(":generateGitProperties").outcome) 36 | assertThat(result.output, containsString("No Git repository found.")) 37 | } 38 | 39 | @Test 40 | public void testPluginSucceedsWithoutGitDirectoryAndFailOnNoGitDirectoryFalse() { 41 | def projectDir = temporaryFolder.newFolder() 42 | new File(projectDir, "settings.gradle") << "" 43 | new File(projectDir, "build.gradle") << """ 44 | plugins { 45 | id('com.gorylenko.gradle-git-properties') 46 | } 47 | gitProperties { 48 | failOnNoGitDirectory = false 49 | } 50 | """.stripIndent() 51 | 52 | def runner = GradleRunner.create() 53 | .withPluginClasspath() 54 | .withArguments("generateGitProperties") 55 | .withProjectDir(projectDir) 56 | 57 | def result = runner.build() 58 | 59 | assertEquals(TaskOutcome.SUCCESS, result.task(":generateGitProperties").outcome) 60 | } 61 | 62 | @Test 63 | public void testPluginSucceedsWithGitDirectory() { 64 | def projectDir = temporaryFolder.newFolder() 65 | 66 | GitRepositoryBuilder.setupProjectDir(projectDir, { gitRepoBuilder -> 67 | // commit 1 new file "hello.txt" 68 | gitRepoBuilder.commitFile("hello.txt", "Hello", "Added hello.txt") 69 | }) 70 | 71 | new File(projectDir, "settings.gradle") << "" 72 | new File(projectDir, "build.gradle") << """ 73 | plugins { 74 | id('com.gorylenko.gradle-git-properties') 75 | } 76 | """.stripIndent() 77 | 78 | def runner = GradleRunner.create() 79 | .withPluginClasspath() 80 | .withArguments("generateGitProperties") 81 | .withProjectDir(projectDir) 82 | 83 | def result = runner.build() 84 | 85 | assertEquals(TaskOutcome.SUCCESS, result.task(":generateGitProperties").outcome) 86 | } 87 | 88 | @Test 89 | public void testPluginSucceedsWithJavaBasePlugin() { 90 | def projectDir = temporaryFolder.newFolder() 91 | 92 | GitRepositoryBuilder.setupProjectDir(projectDir, { gitRepoBuilder -> 93 | // commit 1 new file "hello.txt" 94 | gitRepoBuilder.commitFile("hello.txt", "Hello", "Added hello.txt") 95 | }) 96 | 97 | new File(projectDir, "settings.gradle") << "" 98 | new File(projectDir, "build.gradle") << """ 99 | plugins { 100 | id('java-base') 101 | id('com.gorylenko.gradle-git-properties') 102 | } 103 | """.stripIndent() 104 | 105 | def runner = GradleRunner.create() 106 | .withPluginClasspath() 107 | .withArguments("generateGitProperties") 108 | .withProjectDir(projectDir) 109 | 110 | def result = runner.build() 111 | 112 | assertEquals(TaskOutcome.SUCCESS, result.task(":generateGitProperties").outcome) 113 | } 114 | 115 | @Test 116 | public void testPluginSucceedsWithJavaPlugin() { 117 | def projectDir = temporaryFolder.newFolder() 118 | 119 | GitRepositoryBuilder.setupProjectDir(projectDir, { gitRepoBuilder -> 120 | // commit 1 new file "hello.txt" 121 | gitRepoBuilder.commitFile("hello.txt", "Hello", "Added hello.txt") 122 | }) 123 | 124 | new File(projectDir, "settings.gradle") << "" 125 | new File(projectDir, "build.gradle") << """ 126 | plugins { 127 | id('java') 128 | id('com.gorylenko.gradle-git-properties') 129 | } 130 | """.stripIndent() 131 | 132 | def runner = GradleRunner.create() 133 | .withPluginClasspath() 134 | .withArguments("classes") 135 | .withProjectDir(projectDir) 136 | 137 | def result = runner.build() 138 | 139 | assertEquals(TaskOutcome.SUCCESS, result.task(":generateGitProperties").outcome) 140 | } 141 | } 142 | -------------------------------------------------------------------------------- /src/test/groovy/com/gorylenko/BuildCacheFunctionalTest.groovy: -------------------------------------------------------------------------------- 1 | package com.gorylenko 2 | 3 | import com.gorylenko.properties.GitRepositoryBuilder 4 | import org.gradle.testkit.runner.GradleRunner 5 | import org.gradle.testkit.runner.TaskOutcome 6 | import org.junit.Rule 7 | import org.junit.Test 8 | import org.junit.rules.TemporaryFolder 9 | 10 | import static org.junit.Assert.assertEquals 11 | 12 | public class BuildCacheFunctionalTest { 13 | @Rule 14 | public final TemporaryFolder temporaryFolder = new TemporaryFolder() 15 | 16 | @Test 17 | public void testPluginSupportsBuildCache() { 18 | def projectDir = temporaryFolder.newFolder() 19 | 20 | GitRepositoryBuilder.setupProjectDir(projectDir, { gitRepoBuilder -> 21 | // commit 1 new file "hello.txt" 22 | gitRepoBuilder.commitFile("hello.txt", "Hello", "Added hello.txt") 23 | }) 24 | 25 | new File(projectDir, "settings.gradle") << "" 26 | new File(projectDir, "build.gradle") << """ 27 | plugins { 28 | id('java') 29 | id('com.gorylenko.gradle-git-properties') 30 | } 31 | """.stripIndent() 32 | 33 | def runner = GradleRunner.create() 34 | .withPluginClasspath() 35 | .withArguments("generateGitProperties", "--build-cache") 36 | .withProjectDir(projectDir) 37 | 38 | def firstResult = runner.build() 39 | assertEquals(TaskOutcome.SUCCESS, firstResult.task(":generateGitProperties").outcome) 40 | 41 | def secondResult = runner.build() 42 | assertEquals(TaskOutcome.UP_TO_DATE, secondResult.task(":generateGitProperties").outcome) 43 | 44 | runner.withArguments("clean").build() 45 | 46 | def thirdResult = runner.withArguments("generateGitProperties", "--build-cache").build() 47 | assertEquals(TaskOutcome.FROM_CACHE, thirdResult.task(":generateGitProperties").outcome) 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/test/groovy/com/gorylenko/BuildSrcFunctionalTest.groovy: -------------------------------------------------------------------------------- 1 | package com.gorylenko 2 | 3 | import com.gorylenko.properties.GitRepositoryBuilder 4 | import org.gradle.testkit.runner.GradleRunner 5 | import org.gradle.testkit.runner.TaskOutcome 6 | import org.junit.Rule 7 | import org.junit.Test 8 | import org.junit.rules.TemporaryFolder 9 | 10 | import static org.junit.Assert.assertEquals 11 | import static org.junit.Assert.assertTrue 12 | 13 | public class BuildSrcFunctionalTest { 14 | @Rule 15 | public final TemporaryFolder temporaryFolder = new TemporaryFolder() 16 | 17 | @Test 18 | public void testPluginSucceedsDuringConfigurationPhase() { 19 | def projectDir = temporaryFolder.newFolder() 20 | def runner = GradleRunner.create() 21 | .withPluginClasspath() 22 | .withArguments("check") 23 | .withProjectDir(projectDir) 24 | 25 | def classpathString = runner.pluginClasspath 26 | .collect { "'$it'" } 27 | .join(", ") 28 | 29 | def buildSrcDir = new File(projectDir, "buildSrc") 30 | buildSrcDir.mkdirs() 31 | new File(buildSrcDir, "build.gradle") << """\ 32 | plugins { 33 | id("groovy-gradle-plugin") 34 | } 35 | repositories { 36 | gradlePluginPortal() 37 | } 38 | dependencies { 39 | runtimeClasspath files($classpathString) 40 | } 41 | """ 42 | def pluginSourceDir = buildSrcDir.toPath().resolve("src").resolve("main").resolve("groovy").toFile() 43 | pluginSourceDir.mkdirs() 44 | new File(pluginSourceDir, "test-plugin.gradle") << """\ 45 | plugins { 46 | id("java") 47 | id("com.gorylenko.gradle-git-properties") 48 | } 49 | """ 50 | new File(projectDir, "settings.gradle") << """\ 51 | pluginManagement { 52 | plugins { 53 | id("com.gorylenko.gradle-git-properties") 54 | } 55 | } 56 | """.stripIndent() 57 | new File(projectDir, "build.gradle") << """\ 58 | plugins { 59 | id("test-plugin") 60 | } 61 | """.stripIndent() 62 | 63 | GitRepositoryBuilder.setupProjectDir(projectDir, { gitRepoBuilder -> 64 | // commit 1 new file "hello.txt" 65 | gitRepoBuilder.commitFile("hello.txt", "Hello", "Added hello.txt") 66 | }) 67 | 68 | def result = runner.build() 69 | 70 | assertEquals(TaskOutcome.SUCCESS, result.task(":generateGitProperties").outcome) 71 | } 72 | 73 | @Test 74 | public void testPluginCanOverrideGitPropertiesResourceDir() { 75 | def projectDir = temporaryFolder.newFolder() 76 | def runner = GradleRunner.create() 77 | .withPluginClasspath() 78 | .withArguments("check") 79 | .withProjectDir(projectDir) 80 | 81 | def classpathString = runner.pluginClasspath 82 | .collect { "'$it'" } 83 | .join(", ") 84 | 85 | def buildSrcDir = new File(projectDir, "buildSrc") 86 | buildSrcDir.mkdirs() 87 | def gitPropDir = new File(projectDir, "gitProp") 88 | gitPropDir.mkdirs() 89 | new File(buildSrcDir, "build.gradle") << """\ 90 | plugins { 91 | id("groovy-gradle-plugin") 92 | } 93 | repositories { 94 | gradlePluginPortal() 95 | } 96 | dependencies { 97 | runtimeClasspath files($classpathString) 98 | } 99 | """ 100 | def pluginSourceDir = buildSrcDir.toPath().resolve("src").resolve("main").resolve("groovy").toFile() 101 | pluginSourceDir.mkdirs() 102 | new File(pluginSourceDir, "test-plugin.gradle") << """\ 103 | plugins { 104 | id("java") 105 | id("com.gorylenko.gradle-git-properties") 106 | } 107 | """ 108 | new File(projectDir, "settings.gradle") << """\ 109 | pluginManagement { 110 | plugins { 111 | id("com.gorylenko.gradle-git-properties") 112 | } 113 | } 114 | """.stripIndent() 115 | new File(projectDir, "build.gradle") << """\ 116 | plugins { 117 | id("test-plugin") 118 | } 119 | 120 | gitProperties { 121 | gitPropertiesResourceDir = layout.projectDirectory.dir("gitProp") 122 | } 123 | """.stripIndent() 124 | 125 | GitRepositoryBuilder.setupProjectDir(projectDir, { gitRepoBuilder -> 126 | // commit 1 new file "hello.txt" 127 | gitRepoBuilder.commitFile("hello.txt", "Hello", "Added hello.txt") 128 | }) 129 | 130 | def result = runner.build() 131 | 132 | assertEquals(TaskOutcome.SUCCESS, result.task(":generateGitProperties").outcome) 133 | assertTrue(gitPropDir.list().contains("git.properties")) 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /src/test/groovy/com/gorylenko/ConfigurationCacheFunctionalTest.groovy: -------------------------------------------------------------------------------- 1 | package com.gorylenko 2 | 3 | import com.gorylenko.properties.GitRepositoryBuilder 4 | import org.gradle.testkit.runner.GradleRunner 5 | import org.gradle.testkit.runner.TaskOutcome 6 | import org.junit.Rule 7 | import org.junit.Test 8 | import org.junit.rules.TemporaryFolder 9 | 10 | import static org.junit.Assert.assertEquals 11 | import static org.junit.Assert.assertTrue 12 | 13 | public class ConfigurationCacheFunctionalTest { 14 | @Rule 15 | public final TemporaryFolder temporaryFolder = new TemporaryFolder() 16 | 17 | @Test 18 | public void testPluginSupportsConfigurationCache() { 19 | def projectDir = temporaryFolder.newFolder() 20 | 21 | GitRepositoryBuilder.setupProjectDir(projectDir, { gitRepoBuilder -> 22 | // commit 1 new file "hello.txt" 23 | gitRepoBuilder.commitFile("hello.txt", "Hello", "Added hello.txt") 24 | }) 25 | 26 | new File(projectDir, "settings.gradle") << "" 27 | new File(projectDir, "build.gradle") << """ 28 | plugins { 29 | id('java') 30 | id('com.gorylenko.gradle-git-properties') 31 | } 32 | """.stripIndent() 33 | 34 | def runner = GradleRunner.create() 35 | .withPluginClasspath() 36 | .withArguments("--configuration-cache", "generateGitProperties") 37 | .withProjectDir(projectDir) 38 | 39 | def firstResult = runner.build() 40 | assertEquals(TaskOutcome.SUCCESS, firstResult.task(":generateGitProperties").outcome) 41 | 42 | def secondResult = runner.build() 43 | assertTrue(secondResult.output.contains('Reusing configuration cache.')) 44 | assertEquals(TaskOutcome.UP_TO_DATE, secondResult.task(":generateGitProperties").outcome) 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/test/groovy/com/gorylenko/GitPropertiesPluginTests.groovy: -------------------------------------------------------------------------------- 1 | package com.gorylenko 2 | 3 | import org.gradle.api.GradleException 4 | import org.gradle.api.Project 5 | import org.gradle.testfixtures.ProjectBuilder 6 | import org.junit.After 7 | import org.junit.Before 8 | import org.junit.Test 9 | 10 | import static org.hamcrest.CoreMatchers.startsWith 11 | import static org.junit.Assert.assertEquals 12 | import static org.junit.Assert.assertFalse 13 | import static org.junit.Assert.assertNotNull 14 | import static org.junit.Assert.assertThat 15 | import static org.junit.Assert.assertTrue 16 | import static org.junit.Assert.fail 17 | 18 | class GitPropertiesPluginTests { 19 | 20 | File projectDir 21 | 22 | @Before 23 | public void setUp() throws Exception { 24 | projectDir = File.createTempDir("gradle-git-properties", ".tmp"); 25 | } 26 | 27 | @After 28 | public void tearDown() throws Exception { 29 | projectDir.deleteDir() 30 | } 31 | 32 | @Test 33 | public void testGenerate() { 34 | 35 | // copy this project dir to temp directory (including git repository folder) 36 | new AntBuilder().copy(todir: projectDir) { fileset(dir : ".", defaultexcludes: false) } 37 | 38 | Project project = ProjectBuilder.builder().withProjectDir(projectDir).build() 39 | project.pluginManager.apply 'com.gorylenko.gradle-git-properties' 40 | 41 | // FIXME: Didn't find any way to change `rootProject`, so just set the property. 42 | GitPropertiesPluginExtension ext = project.getExtensions().getByName("gitProperties") 43 | ext.dotGitDirectory.set(new File(projectDir, '.git')) 44 | 45 | def task = project.tasks.generateGitProperties 46 | assertTrue(task instanceof GenerateGitPropertiesTask) 47 | 48 | task.generate() 49 | 50 | def gitPropertiesFile = project.buildDir.getAbsolutePath() + '/resources/main/git.properties' 51 | 52 | Properties properties = new Properties() 53 | properties.load(new FileInputStream(gitPropertiesFile)) 54 | GitProperties.standardProperties.each{ 55 | assertNotNull(properties.getProperty(it)) 56 | } 57 | } 58 | 59 | @Test 60 | public void testGenerateWithMissingGitRepoShouldNotFail() { 61 | 62 | Project project = ProjectBuilder.builder().withProjectDir(projectDir).build() 63 | project.pluginManager.apply 'com.gorylenko.gradle-git-properties' 64 | 65 | // FIXME: Didn't find any way to change `rootProject`, so just set the property. 66 | GitPropertiesPluginExtension ext = project.getExtensions().getByName("gitProperties") 67 | ext.dotGitDirectory.set(projectDir) 68 | ext.failOnNoGitDirectory = false; 69 | 70 | def task = project.tasks.generateGitProperties 71 | assertTrue(task instanceof GenerateGitPropertiesTask) 72 | 73 | task.generate() 74 | 75 | def gitPropertiesFile = project.buildDir.getAbsolutePath() + '/resources/main/git.properties' 76 | assertFalse(new File(gitPropertiesFile).exists()) 77 | } 78 | 79 | @Test 80 | public void testGenerateWithMissingGitRepoShouldFail() { 81 | 82 | Project project = ProjectBuilder.builder().withProjectDir(projectDir).build() 83 | project.pluginManager.apply 'com.gorylenko.gradle-git-properties' 84 | 85 | // FIXME: Didn't find any way to change `rootProject`, so just set the property. 86 | GitPropertiesPluginExtension ext = project.getExtensions().getByName("gitProperties") 87 | ext.dotGitDirectory.set(projectDir) 88 | // failOnNoGitDirectory is true by default 89 | 90 | def task = project.tasks.getByName("generateGitProperties") 91 | assertTrue(task instanceof GenerateGitPropertiesTask) 92 | 93 | try { 94 | task.generate() 95 | fail('should have gotten a GradleException') 96 | } catch (Exception e) { 97 | assertEquals(GradleException, e.class) 98 | assertThat(e.message, startsWith("No Git repository found.")) 99 | } 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /src/test/groovy/com/gorylenko/GitPropertiesTest.groovy: -------------------------------------------------------------------------------- 1 | package com.gorylenko 2 | 3 | import static org.junit.Assert.* 4 | 5 | import java.io.File 6 | import java.nio.file.Files 7 | import java.nio.file.StandardCopyOption 8 | import org.ajoberstar.grgit.Grgit 9 | import org.junit.After 10 | import org.junit.Before 11 | import org.junit.Test 12 | 13 | import com.gorylenko.properties.GitRepositoryBuilder 14 | 15 | class GitPropertiesTest { 16 | 17 | File projectDir 18 | File dotGitDirectory 19 | GitProperties props = new GitProperties() 20 | 21 | @Before 22 | public void setUp() throws Exception { 23 | 24 | // Set up projectDir 25 | 26 | projectDir = File.createTempDir("BranchPropertyTest", ".tmp") 27 | dotGitDirectory = new File(projectDir, '.git') 28 | 29 | GitRepositoryBuilder.setupProjectDir(projectDir, { }) 30 | } 31 | 32 | @After 33 | public void tearDown() throws Exception { 34 | projectDir.deleteDir() 35 | } 36 | 37 | @Test 38 | public void getStandardProperties() { 39 | assertTrue(GitProperties.standardProperties.size() >= 19) 40 | } 41 | 42 | 43 | @Test 44 | public void testGenerateAllPropsOnEmptyRepo() { 45 | 46 | List keys = GitProperties.standardProperties 47 | String dateFormat 48 | String dateFormatTimeZone 49 | String branch 50 | String buildVersion = "1.0" 51 | Map customProperties = [:] 52 | 53 | Map generated = props.generate(dotGitDirectory, keys, dateFormat, dateFormatTimeZone, branch, buildVersion, customProperties) 54 | 55 | GitProperties.standardProperties.each { 56 | assertNotNull(generated[it]) 57 | } 58 | } 59 | 60 | @Test 61 | public void testGenerateAllPropsOnNonEmptyRepo() { 62 | 63 | GitRepositoryBuilder.setupProjectDir(projectDir, { gitRepoBuilder -> 64 | gitRepoBuilder.commitFile("hello.txt", "Hello", "Added hello.txt") 65 | }) 66 | 67 | List keys = GitProperties.standardProperties 68 | String dateFormat 69 | String dateFormatTimeZone 70 | String branch 71 | String buildVersion = "1.0" 72 | Map customProperties = ['test' : { return 10 }] 73 | 74 | Map generated = props.generate(dotGitDirectory, keys, dateFormat, dateFormatTimeZone, branch, buildVersion, customProperties) 75 | 76 | GitProperties.standardProperties.each { 77 | assertNotNull(generated[it]) 78 | } 79 | assertEquals('10', generated['test']) 80 | } 81 | 82 | 83 | @Test 84 | public void testGenerateSelectedWithUserDefinedBranchProps() { 85 | GitRepositoryBuilder.setupProjectDir(projectDir, { gitRepoBuilder -> 86 | gitRepoBuilder.commitFile("hello.txt", "Hello", "Added hello.txt") 87 | // add TAGONE to firstCommit (current HEAD) 88 | gitRepoBuilder.addTag("TAGONE") 89 | }) 90 | 91 | List keys = ['git.branch','git.commit.id.describe'] 92 | String dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ" 93 | String dateFormatTimeZone = "PST" 94 | String branch = "mybranch" 95 | String buildVersion = "1.0" 96 | Map customProperties = [:] 97 | 98 | Map generated = props.generate(dotGitDirectory, keys, dateFormat, dateFormatTimeZone, branch, buildVersion, customProperties) 99 | 100 | assertEquals(2, generated.size()) 101 | assertEquals('mybranch', generated['git.branch']) 102 | assertEquals("TAGONE", generated['git.commit.id.describe']) 103 | } 104 | 105 | @Test 106 | public void testGenerateSelectedProps() { 107 | GitRepositoryBuilder.setupProjectDir(projectDir, { gitRepoBuilder -> 108 | gitRepoBuilder.commitFile("hello.txt", "Hello", "Added hello.txt") 109 | }) 110 | 111 | List keys = ['git.branch','git.commit.id','git.commit.time'] 112 | String dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ" 113 | String dateFormatTimeZone = "PST" 114 | String branch 115 | String buildVersion = "1.0" 116 | Map customProperties = [:] 117 | 118 | Map generated = props.generate(dotGitDirectory, keys, dateFormat, dateFormatTimeZone, branch, buildVersion, customProperties) 119 | 120 | assertEquals(3, generated.size()) 121 | assertEquals('master', generated['git.branch']) 122 | assertNotNull(generated['git.commit.id']) 123 | assertNotNull(generated['git.commit.time']) 124 | } 125 | 126 | @Test 127 | public void testGenerateAllPropsOnShalowClonedRepo() { 128 | 129 | 130 | List keys = GitProperties.standardProperties 131 | String dateFormat 132 | String dateFormatTimeZone 133 | String branch 134 | String buildVersion = "1.0" 135 | Map customProperties = ['test' : { return 10 }] 136 | 137 | 138 | File tmpDir = File.createTempDir("BranchPropertyTestShallowClone", ".tmp") 139 | Grgit repo1 = null 140 | 141 | try { 142 | InputStream is = GitPropertiesTest.class.getResourceAsStream('/shallowclone3.zip') 143 | 144 | is.withStream { Files.copy(it, new File(tmpDir, "shallowclone3.zip").toPath(), StandardCopyOption.REPLACE_EXISTING) } 145 | 146 | AntBuilder ant = new AntBuilder(); 147 | 148 | ant.unzip(src: new File(tmpDir, "shallowclone3.zip") ,dest: tmpDir, overwrite:"true" ) 149 | 150 | repo1 = Grgit.open(dir: new File(tmpDir, "shallowclone3")) 151 | 152 | Map generated = props.generate(dotGitDirectory, keys, dateFormat, dateFormatTimeZone, branch, buildVersion, customProperties) 153 | 154 | GitProperties.standardProperties.each { 155 | assertNotNull(generated[it]) 156 | } 157 | assertEquals('10', generated['test']) 158 | 159 | } finally { 160 | repo1?.close() 161 | tmpDir.deleteDir() 162 | } 163 | 164 | 165 | } 166 | 167 | } 168 | -------------------------------------------------------------------------------- /src/test/groovy/com/gorylenko/PropertiesFileWriterTest.groovy: -------------------------------------------------------------------------------- 1 | package com.gorylenko 2 | 3 | import org.junit.Before 4 | import org.junit.Test 5 | 6 | import static org.junit.Assert.assertEquals 7 | import static org.junit.Assert.assertNotEquals 8 | import static org.junit.Assert.assertTrue 9 | 10 | class PropertiesFileWriterTest { 11 | 12 | PropertiesFileWriter writer 13 | 14 | @Before 15 | public void setUp() throws Exception { 16 | writer = new PropertiesFileWriter() 17 | } 18 | 19 | @Test 20 | public void testWriteNormalProperties() { 21 | 22 | File file = File.createTempFile("temp",".tmp") 23 | writer.write([greeting: 'Hello'], file, true) 24 | 25 | Properties props = loadProperties(file) 26 | assertEquals(props, [greeting: 'Hello']) 27 | } 28 | 29 | @Test 30 | public void testWritingSameContent() { 31 | 32 | // Set up a Properties file with greeting=Hello 33 | File file = File.createTempFile("temp",".tmp") 34 | Properties props = new Properties() 35 | props.setProperty('greeting', 'Hello') 36 | file.withOutputStream { 37 | props.store(it, null) 38 | } 39 | 40 | // Write to same file with same content (force=false) 41 | writer.write([greeting: 'Hello'], file, false) 42 | 43 | // Write to same file with same content (force=true) 44 | writer.write([greeting: 'Hello'], file, true) 45 | } 46 | 47 | 48 | @Test 49 | public void testWritingDifferentContent() { 50 | 51 | // write a Properties file with greeting=Hello 52 | File file = File.createTempFile("temp",".tmp") 53 | Properties props = new Properties() 54 | props.setProperty('greeting', 'Hello') 55 | file.withOutputStream { 56 | props.store(it, null) 57 | } 58 | 59 | // Try to write to same file with different content 60 | writer.write([greeting: 'Hello2'], file, false) 61 | 62 | // Make sure content is updated 63 | assertEquals(loadProperties(file), [greeting: 'Hello2']) 64 | } 65 | 66 | private Properties loadProperties(File file) { 67 | def props = new Properties() 68 | file.withInputStream { 69 | props.load it 70 | } 71 | return props 72 | } 73 | 74 | 75 | @Test 76 | public void testWriteNormalPropertiesResultMustBeSorted() { 77 | 78 | File file = File.createTempFile("temp",".tmp") 79 | writer.write([greeting_3: 'Hello', greeting_1: 'Hello', greeting_2: 'Hello', greeting_4: 'Hello'], file, true) 80 | 81 | String result = file.text 82 | int index1 = result.indexOf("greeting_1") 83 | int index2 = result.indexOf("greeting_2") 84 | int index3 = result.indexOf("greeting_3") 85 | int index4 = result.indexOf("greeting_4") 86 | 87 | assertTrue(index1 < index2) 88 | assertTrue(index2 < index3) 89 | assertTrue(index3 < index4) 90 | } 91 | 92 | @Test 93 | public void shouldNotContainComments() { 94 | // given: 95 | def map = [greeting_3: 'Hello', greeting_1: 'Hello', greeting_2: 'Hello'] 96 | File file = File.createTempFile("temp", ".tmp") 97 | 98 | // when: 99 | writer.write(map, file, true) 100 | def lines = file.text.readLines() 101 | def nonEmptyLines = lines.findAll { it.length() > 0 } 102 | def hasComments = lines.findAll({ it.startsWith("#") }) 103 | .isEmpty() 104 | 105 | // then: 106 | assertTrue("git.properties should not contain comments", hasComments) 107 | assertEquals(map.size(), lines.size()) 108 | assertEquals(map.size(), nonEmptyLines.size()) 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /src/test/groovy/com/gorylenko/properties/BranchPropertyTest.groovy: -------------------------------------------------------------------------------- 1 | package com.gorylenko.properties 2 | 3 | import static org.junit.Assert.* 4 | 5 | import java.util.Map 6 | 7 | import org.ajoberstar.grgit.Commit 8 | import org.ajoberstar.grgit.Grgit 9 | import org.ajoberstar.grgit.Person 10 | import org.junit.After 11 | import org.junit.Before 12 | import org.junit.Test 13 | 14 | class BranchPropertyTest { 15 | 16 | File projectDir 17 | Grgit repo 18 | 19 | @Before 20 | public void setUp() throws Exception { 21 | 22 | // Set up projectDir 23 | 24 | projectDir = File.createTempDir("BranchPropertyTest", ".tmp") 25 | 26 | GitRepositoryBuilder.setupProjectDir(projectDir, { gitRepoBuilder -> 27 | // empty repo 28 | }) 29 | 30 | 31 | // Set up repo 32 | repo = Grgit.open(dir: projectDir) 33 | 34 | } 35 | 36 | @After 37 | public void tearDown() throws Exception { 38 | repo?.close() 39 | projectDir.deleteDir() 40 | } 41 | 42 | // Must always override getEnv() for object under test otherwise the tests will fail on CI servers because of environment variables 43 | BranchProperty getTestObject(String branch, Map env) { 44 | BranchProperty instance = new BranchProperty(branch) 45 | instance.setEnv(env) 46 | return instance 47 | } 48 | 49 | @Test 50 | public void testDoCallOnEmptyRepo() { 51 | BranchProperty prop = getTestObject(null, [:]) 52 | assertEquals('', prop.doCall(repo)) 53 | } 54 | 55 | @Test 56 | public void testDoCallOnEmptyRepoWithUserDefinedBranch() { 57 | BranchProperty prop = getTestObject("mybranch", [:]) 58 | assertEquals('mybranch', prop.doCall(repo)) 59 | } 60 | 61 | @Test 62 | public void testDoCallOnMasterBranch() { 63 | 64 | GitRepositoryBuilder.setupProjectDir(projectDir, { gitRepoBuilder -> 65 | 66 | // commit 1 new file "hello.txt" 67 | gitRepoBuilder.commitFile("hello.txt", "Hello", "Added hello.txt") 68 | 69 | // create a new branch "branch-1" at current location 70 | gitRepoBuilder.addBranch("branch-1") 71 | 72 | // commit 1 new file "hello2.txt" 73 | gitRepoBuilder.commitFile("hello2.txt", "Hello2", "Added hello2.txt") 74 | }) 75 | 76 | BranchProperty prop = getTestObject(null, [:]) 77 | assertEquals("master", prop.doCall(repo)) 78 | } 79 | 80 | @Test 81 | public void testDoCallOnBranch1() { 82 | 83 | GitRepositoryBuilder.setupProjectDir(projectDir, { gitRepoBuilder -> 84 | 85 | // commit 1 new file "hello.txt" 86 | gitRepoBuilder.commitFile("hello.txt", "Hello", "Added hello.txt") 87 | 88 | // create a new branch "branch-1" at current location 89 | gitRepoBuilder.addBranch("branch-1") 90 | 91 | // commit 1 new file "hello2.txt" 92 | gitRepoBuilder.commitFile("hello2.txt", "Hello2", "Added hello2.txt") 93 | }) 94 | 95 | repo.checkout (branch : "branch-1") 96 | 97 | BranchProperty prop = getTestObject(null, [:]) 98 | assertEquals("branch-1", prop.doCall(repo)) 99 | } 100 | 101 | @Test 102 | public void testDoCallWithUserDefinedBranch() { 103 | 104 | GitRepositoryBuilder.setupProjectDir(projectDir, { gitRepoBuilder -> 105 | 106 | // commit 1 new file "hello.txt" 107 | gitRepoBuilder.commitFile("hello.txt", "Hello", "Added hello.txt") 108 | 109 | // create a new branch "branch-1" at current location 110 | gitRepoBuilder.addBranch("branch-1") 111 | 112 | // commit 1 new file "hello2.txt" 113 | gitRepoBuilder.commitFile("hello2.txt", "Hello2", "Added hello2.txt") 114 | }) 115 | 116 | assertEquals("mybranch", getTestObject("mybranch", [:]).doCall(repo)) 117 | assertEquals("mybranch", getTestObject("mybranch", [JOB_NAME: 'MyJob', GIT_LOCAL_BRANCH: 'local-branch']).doCall(repo)) 118 | assertEquals("mybranch", getTestObject("mybranch", [JOB_NAME: 'MyJob', GIT_BRANCH: 'git-branch']).doCall(repo)) 119 | assertEquals("mybranch", getTestObject("mybranch", [TRAVIS: 'true', TRAVIS_BRANCH: 'local-branch']).doCall(repo)) 120 | assertEquals("mybranch", getTestObject("mybranch", [TEAMCITY_VERSION: '1', 'teamcity.build.branch': 'local-branch']).doCall(repo)) 121 | assertEquals("mybranch", getTestObject("mybranch", [GITLAB_CI: 'true', 'CI_COMMIT_REF_NAME': 'local-branch']).doCall(repo)) 122 | assertEquals("mybranch", getTestObject("mybranch", [BAMBOO_BUILDKEY: 'true', 'BAMBOO_PLANREPOSITORY_BRANCH': 'local-branch']).doCall(repo)) 123 | } 124 | 125 | @Test 126 | public void testDoCallOnJenkinsServer() { 127 | 128 | GitRepositoryBuilder.setupProjectDir(projectDir, { gitRepoBuilder -> 129 | 130 | // commit 1 new file "hello.txt" 131 | gitRepoBuilder.commitFile("hello.txt", "Hello", "Added hello.txt") 132 | 133 | // create a new branch "branch-1" at current location 134 | gitRepoBuilder.addBranch("branch-1") 135 | 136 | }) 137 | 138 | repo.checkout (branch : "master") 139 | 140 | BranchProperty prop = getTestObject(null, [JOB_NAME: 'MyJob', GIT_LOCAL_BRANCH: 'local-branch']) 141 | assertEquals("local-branch", prop.doCall(repo)) 142 | 143 | 144 | BranchProperty prop2 = getTestObject(null, [JOB_NAME: 'MyJob', GIT_BRANCH: 'git-branch']) 145 | assertEquals("git-branch", prop2.doCall(repo)) 146 | } 147 | 148 | @Test 149 | public void testDoCallOnTravisServer() { 150 | 151 | GitRepositoryBuilder.setupProjectDir(projectDir, { gitRepoBuilder -> 152 | 153 | // commit 1 new file "hello.txt" 154 | gitRepoBuilder.commitFile("hello.txt", "Hello", "Added hello.txt") 155 | 156 | // create a new branch "branch-1" at current location 157 | gitRepoBuilder.addBranch("branch-1") 158 | 159 | }) 160 | 161 | repo.checkout (branch : "master") 162 | 163 | BranchProperty prop = getTestObject(null, [TRAVIS: 'true', TRAVIS_BRANCH: 'local-branch']) 164 | assertEquals("local-branch", prop.doCall(repo)) 165 | 166 | 167 | } 168 | 169 | @Test 170 | public void testDoCallOnTeamCityServer() { 171 | 172 | GitRepositoryBuilder.setupProjectDir(projectDir, { gitRepoBuilder -> 173 | 174 | // commit 1 new file "hello.txt" 175 | gitRepoBuilder.commitFile("hello.txt", "Hello", "Added hello.txt") 176 | 177 | // create a new branch "branch-1" at current location 178 | gitRepoBuilder.addBranch("branch-1") 179 | 180 | }) 181 | 182 | repo.checkout (branch : "master") 183 | 184 | BranchProperty prop = getTestObject(null, [TEAMCITY_VERSION: '1', 'teamcity.build.branch': 'local-branch']) 185 | assertEquals("local-branch", prop.doCall(repo)) 186 | 187 | 188 | } 189 | 190 | @Test 191 | public void testDoCallOnGitlab() { 192 | 193 | GitRepositoryBuilder.setupProjectDir(projectDir, { gitRepoBuilder -> 194 | 195 | // commit 1 new file "hello.txt" 196 | gitRepoBuilder.commitFile("hello.txt", "Hello", "Added hello.txt") 197 | 198 | // create a new branch "branch-1" at current location 199 | gitRepoBuilder.addBranch("branch-1") 200 | 201 | }) 202 | 203 | repo.checkout (branch : "master") 204 | 205 | BranchProperty prop = getTestObject(null, [GITLAB_CI: 'true', 'CI_COMMIT_REF_NAME': 'local-branch']) 206 | assertEquals("local-branch", prop.doCall(repo)) 207 | } 208 | 209 | @Test 210 | public void testDoCallOnBamboo() { 211 | 212 | GitRepositoryBuilder.setupProjectDir(projectDir, { gitRepoBuilder -> 213 | 214 | // commit 1 new file "hello.txt" 215 | gitRepoBuilder.commitFile("hello.txt", "Hello", "Added hello.txt") 216 | 217 | // create a new branch "branch-1" at current location 218 | gitRepoBuilder.addBranch("branch-1") 219 | 220 | }) 221 | 222 | repo.checkout (branch : "master") 223 | 224 | BranchProperty prop = getTestObject(null, [BAMBOO_BUILDKEY: 'true', 'BAMBOO_PLANREPOSITORY_BRANCH': 'local-branch']) 225 | assertEquals("local-branch", prop.doCall(repo)) 226 | } 227 | 228 | } 229 | -------------------------------------------------------------------------------- /src/test/groovy/com/gorylenko/properties/BuildHostPropertyTest.groovy: -------------------------------------------------------------------------------- 1 | package com.gorylenko.properties 2 | 3 | import static org.junit.Assert.* 4 | 5 | import org.junit.Test 6 | 7 | class BuildHostPropertyTest { 8 | 9 | @Test 10 | public void testDoCall() { 11 | assertNotNull(new BuildHostProperty().doCall(null)) 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /src/test/groovy/com/gorylenko/properties/BuildUserEmailPropertyTest.groovy: -------------------------------------------------------------------------------- 1 | package com.gorylenko.properties 2 | 3 | import static org.junit.Assert.* 4 | 5 | import java.io.File 6 | import java.text.SimpleDateFormat 7 | import org.ajoberstar.grgit.Commit 8 | import org.ajoberstar.grgit.Grgit 9 | import org.junit.After 10 | import org.junit.Before 11 | import org.junit.Test 12 | 13 | class BuildUserEmailPropertyTest { 14 | 15 | File projectDir 16 | Grgit repo 17 | 18 | @Before 19 | public void setUp() throws Exception { 20 | 21 | // Set up projectDir 22 | 23 | projectDir = File.createTempDir("BranchPropertyTest", ".tmp") 24 | GitRepositoryBuilder.setupProjectDir(projectDir, { }) 25 | 26 | // Set up repo 27 | repo = Grgit.open(dir: projectDir) 28 | 29 | } 30 | 31 | @After 32 | public void tearDown() throws Exception { 33 | repo?.close() 34 | projectDir.deleteDir() 35 | } 36 | 37 | 38 | @Test 39 | public void testDoCallWithoutConfiguredUserName() { 40 | GitRepositoryBuilder.setupProjectDir(projectDir, { gitRepoBuilder -> 41 | gitRepoBuilder.setConfigString("user", null, "email", null) 42 | // commit 1 new file "hello.txt" 43 | gitRepoBuilder.commitFile("hello.txt", "Hello", "Added hello.txt") 44 | }) 45 | 46 | assertEquals('', new BuildUserEmailProperty().doCall(repo)) 47 | } 48 | 49 | 50 | @Test 51 | public void testDoCallWithConfiguredUserName() { 52 | GitRepositoryBuilder.setupProjectDir(projectDir, { gitRepoBuilder -> 53 | gitRepoBuilder.setConfigString("user", null, "email", "test@example.com") 54 | // commit 1 new file "hello.txt" 55 | gitRepoBuilder.commitFile("hello.txt", "Hello", "Added hello.txt") 56 | }) 57 | assertEquals("test@example.com", new BuildUserEmailProperty().doCall(repo)) 58 | } 59 | 60 | 61 | } 62 | -------------------------------------------------------------------------------- /src/test/groovy/com/gorylenko/properties/BuildUserNamePropertyTest.groovy: -------------------------------------------------------------------------------- 1 | package com.gorylenko.properties 2 | 3 | import static org.junit.Assert.* 4 | 5 | import java.io.File 6 | import java.text.SimpleDateFormat 7 | import org.ajoberstar.grgit.Commit 8 | import org.ajoberstar.grgit.Grgit 9 | import org.junit.After 10 | import org.junit.Before 11 | import org.junit.Test 12 | 13 | class BuildUserNamePropertyTest { 14 | 15 | File projectDir 16 | Grgit repo 17 | 18 | @Before 19 | public void setUp() throws Exception { 20 | 21 | // Set up projectDir 22 | 23 | projectDir = File.createTempDir("BranchPropertyTest", ".tmp") 24 | GitRepositoryBuilder.setupProjectDir(projectDir, { }) 25 | 26 | // Set up repo 27 | repo = Grgit.open(dir: projectDir) 28 | 29 | } 30 | 31 | @After 32 | public void tearDown() throws Exception { 33 | repo?.close() 34 | projectDir.deleteDir() 35 | } 36 | 37 | 38 | @Test 39 | public void testDoCallWithoutConfiguredUserName() { 40 | GitRepositoryBuilder.setupProjectDir(projectDir, { gitRepoBuilder -> 41 | gitRepoBuilder.setConfigString("user", null, "name", null) 42 | // commit 1 new file "hello.txt" 43 | gitRepoBuilder.commitFile("hello.txt", "Hello", "Added hello.txt") 44 | }) 45 | 46 | assertEquals('', new BuildUserNameProperty().doCall(repo)) 47 | } 48 | 49 | 50 | @Test 51 | public void testDoCallWithConfiguredUserName() { 52 | GitRepositoryBuilder.setupProjectDir(projectDir, { gitRepoBuilder -> 53 | gitRepoBuilder.setConfigString("user", null, "name", "Test User") 54 | // commit 1 new file "hello.txt" 55 | gitRepoBuilder.commitFile("hello.txt", "Hello", "Added hello.txt") 56 | }) 57 | assertEquals("Test User", new BuildUserNameProperty().doCall(repo)) 58 | } 59 | 60 | 61 | } 62 | -------------------------------------------------------------------------------- /src/test/groovy/com/gorylenko/properties/BuildVersionPropertyTest.groovy: -------------------------------------------------------------------------------- 1 | package com.gorylenko.properties 2 | 3 | import static org.junit.Assert.* 4 | 5 | import org.junit.Test 6 | 7 | class BuildVersionPropertyTest { 8 | 9 | @Test 10 | public void testDoCall() { 11 | assertEquals("1.0", new BuildVersionProperty("1.0").doCall(null)) 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /src/test/groovy/com/gorylenko/properties/ClosestTagCommitCountPropertyTest.groovy: -------------------------------------------------------------------------------- 1 | package com.gorylenko.properties 2 | 3 | import static org.junit.Assert.* 4 | 5 | import java.io.File 6 | import java.nio.file.Files 7 | import java.nio.file.StandardCopyOption 8 | import org.ajoberstar.grgit.Commit 9 | import org.ajoberstar.grgit.Grgit 10 | import org.junit.After 11 | import org.junit.Before 12 | import org.junit.Test 13 | 14 | class ClosestTagCommitCountPropertyTest { 15 | 16 | File projectDir 17 | Grgit repo 18 | 19 | @Before 20 | public void setUp() throws Exception { 21 | 22 | // Set up projectDir 23 | 24 | projectDir = File.createTempDir("BranchPropertyTest", ".tmp") 25 | GitRepositoryBuilder.setupProjectDir(projectDir, { gitRepoBuilder -> 26 | // empty repo 27 | }) 28 | 29 | // Set up repo 30 | repo = Grgit.open(dir: projectDir) 31 | } 32 | 33 | private ClosestTagCommitCountProperty createTarget() { 34 | new ClosestTagCommitCountProperty(new CacheSupport()) 35 | } 36 | 37 | @After 38 | public void tearDown() throws Exception { 39 | repo?.close() 40 | projectDir.deleteDir() 41 | } 42 | 43 | 44 | @Test 45 | public void testDoCallOnEmptyRepo() { 46 | assertEquals('', createTarget().doCall(repo)) 47 | } 48 | 49 | @Test 50 | public void testDoCallNoTag() { 51 | GitRepositoryBuilder.setupProjectDir(projectDir, { gitRepoBuilder -> 52 | // commit 1 new file "hello.txt" 53 | gitRepoBuilder.commitFile("hello.txt", "Hello", "Added hello.txt") 54 | }) 55 | assertEquals('', createTarget().doCall(repo)) 56 | } 57 | 58 | @Test 59 | public void testDoCallOneTag() { 60 | 61 | GitRepositoryBuilder.setupProjectDir(projectDir, { gitRepoBuilder -> 62 | // commit 1 new file "hello.txt" 63 | gitRepoBuilder.commitFile("hello.txt", "Hello", "Added hello.txt") 64 | // add TAGONE to firstCommit (current HEAD) 65 | gitRepoBuilder.addTag("TAGONE") 66 | }) 67 | 68 | assertEquals("0", createTarget().doCall(repo)) 69 | } 70 | 71 | @Test 72 | public void testDoCallOneTagOneCommit() { 73 | GitRepositoryBuilder.setupProjectDir(projectDir, { gitRepoBuilder -> 74 | // commit 1 new file "hello.txt" 75 | gitRepoBuilder.commitFile("hello.txt", "Hello", "Added hello.txt") 76 | // add TAGONE to firstCommit (current HEAD) 77 | gitRepoBuilder.addTag("TAGONE") 78 | gitRepoBuilder.commitFile("hello.txt", "Hello", "Added hello.txt") 79 | }) 80 | 81 | assertEquals("1", createTarget().doCall(repo)) 82 | } 83 | 84 | @Test 85 | public void testDoCallOneTagOneCommitSecondTag() { 86 | GitRepositoryBuilder.setupProjectDir(projectDir, { gitRepoBuilder -> 87 | // commit 1 new file "hello.txt" 88 | gitRepoBuilder.commitFile("hello.txt", "Hello", "Added hello.txt") 89 | // add TAGONE to firstCommit (current HEAD) 90 | gitRepoBuilder.addTag("TAGONE") 91 | gitRepoBuilder.commitFile("hello.txt", "Hello", "Added hello.txt") 92 | gitRepoBuilder.addTag("TAGTWO") 93 | }) 94 | 95 | assertEquals("0", createTarget().doCall(repo)) 96 | } 97 | 98 | @Test 99 | public void testDoCallOneTagOneCommitShallowClone() { 100 | 101 | File tmpDir = File.createTempDir("BranchPropertyTestShallowClone", ".tmp") 102 | Grgit repo1 = null 103 | 104 | try { 105 | InputStream is = ClosestTagCommitCountPropertyTest.class.getResourceAsStream('/shallowclone3.zip') 106 | 107 | is.withStream { Files.copy(it, new File(tmpDir, "shallowclone3.zip").toPath(), StandardCopyOption.REPLACE_EXISTING) } 108 | 109 | AntBuilder ant = new AntBuilder(); 110 | 111 | ant.unzip(src: new File(tmpDir, "shallowclone3.zip") ,dest: tmpDir, overwrite:"true" ) 112 | 113 | repo1 = Grgit.open(dir: new File(tmpDir, "shallowclone3")) 114 | 115 | assertEquals("", createTarget().doCall(repo1)) 116 | 117 | } finally { 118 | repo1?.close() 119 | tmpDir.deleteDir() 120 | } 121 | 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /src/test/groovy/com/gorylenko/properties/ClosestTagNamePropertyTest.groovy: -------------------------------------------------------------------------------- 1 | package com.gorylenko.properties 2 | 3 | import static org.junit.Assert.* 4 | 5 | import java.io.File 6 | import java.nio.file.Files 7 | import java.nio.file.StandardCopyOption 8 | import org.ajoberstar.grgit.Commit 9 | import org.ajoberstar.grgit.Grgit 10 | import org.junit.After 11 | import org.junit.Before 12 | import org.junit.Test 13 | 14 | class ClosestTagNamePropertyTest { 15 | 16 | File projectDir 17 | Grgit repo 18 | 19 | @Before 20 | public void setUp() throws Exception { 21 | 22 | // Set up projectDir 23 | 24 | projectDir = File.createTempDir("BranchPropertyTest", ".tmp") 25 | GitRepositoryBuilder.setupProjectDir(projectDir, { gitRepoBuilder -> 26 | // empty repo 27 | }) 28 | 29 | // Set up repo 30 | repo = Grgit.open(dir: projectDir) 31 | } 32 | 33 | private ClosestTagNameProperty createTarget() { 34 | new ClosestTagNameProperty(new CacheSupport()) 35 | } 36 | 37 | @After 38 | public void tearDown() throws Exception { 39 | repo?.close() 40 | projectDir.deleteDir() 41 | } 42 | 43 | 44 | @Test 45 | public void testDoCallOnEmptyRepo() { 46 | assertEquals('', createTarget().doCall(repo)) 47 | } 48 | 49 | 50 | @Test 51 | public void testDoCallNoTag() { 52 | GitRepositoryBuilder.setupProjectDir(projectDir, { gitRepoBuilder -> 53 | // commit 1 new file "hello.txt" 54 | gitRepoBuilder.commitFile("hello.txt", "Hello", "Added hello.txt") 55 | }) 56 | assertEquals('', createTarget().doCall(repo)) 57 | } 58 | 59 | @Test 60 | public void testDoCallOneTag() { 61 | 62 | GitRepositoryBuilder.setupProjectDir(projectDir, { gitRepoBuilder -> 63 | // commit 1 new file "hello.txt" 64 | gitRepoBuilder.commitFile("hello.txt", "Hello", "Added hello.txt") 65 | 66 | // add TAGONE to firstCommit (current HEAD) 67 | gitRepoBuilder.addTag("TAGONE") 68 | }) 69 | 70 | assertEquals("TAGONE", createTarget().doCall(repo)) 71 | } 72 | 73 | @Test 74 | public void testDoCallOneTagOneCommit() { 75 | GitRepositoryBuilder.setupProjectDir(projectDir, { gitRepoBuilder -> 76 | // commit 1 new file "hello.txt" 77 | gitRepoBuilder.commitFile("hello.txt", "Hello", "Added hello.txt") 78 | 79 | // add TAGONE to firstCommit (current HEAD) 80 | gitRepoBuilder.addTag("TAGONE") 81 | gitRepoBuilder.commitFile("hello.txt", "Hello", "Added hello.txt") 82 | }) 83 | 84 | assertEquals("TAGONE", createTarget().doCall(repo)) 85 | } 86 | 87 | @Test 88 | public void testDoCallOneTagOneCommitSecondTag() { 89 | GitRepositoryBuilder.setupProjectDir(projectDir, { gitRepoBuilder -> 90 | // commit 1 new file "hello.txt" 91 | gitRepoBuilder.commitFile("hello.txt", "Hello", "Added hello.txt") 92 | 93 | // add TAGONE to firstCommit (current HEAD) 94 | gitRepoBuilder.addTag("TAGONE") 95 | gitRepoBuilder.commitFile("hello.txt", "Hello", "Added hello.txt") 96 | gitRepoBuilder.addTag("TAGTWO") 97 | }) 98 | 99 | assertEquals("TAGTWO", createTarget().doCall(repo)) 100 | } 101 | 102 | @Test 103 | public void testDoCallOneTagOneCommitShallowClone() { 104 | 105 | File tmpDir = File.createTempDir("BranchPropertyTestShallowClone", ".tmp") 106 | Grgit repo1 = null 107 | 108 | try { 109 | InputStream is = ClosestTagNamePropertyTest.class.getResourceAsStream('/shallowclone3.zip') 110 | 111 | is.withStream { Files.copy(it, new File(tmpDir, "shallowclone3.zip").toPath(), StandardCopyOption.REPLACE_EXISTING) } 112 | 113 | AntBuilder ant = new AntBuilder(); 114 | 115 | ant.unzip(src: new File(tmpDir, "shallowclone3.zip") ,dest: tmpDir, overwrite:"true" ) 116 | 117 | repo1 = Grgit.open(dir: new File(tmpDir, "shallowclone3")) 118 | 119 | assertEquals("", createTarget().doCall(repo1)) 120 | 121 | } finally { 122 | repo1?.close() 123 | tmpDir.deleteDir() 124 | } 125 | 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /src/test/groovy/com/gorylenko/properties/CommitIdAbbrevPropertyTest.groovy: -------------------------------------------------------------------------------- 1 | package com.gorylenko.properties 2 | 3 | import static org.junit.Assert.* 4 | 5 | import java.io.File 6 | import org.ajoberstar.grgit.Commit 7 | import org.ajoberstar.grgit.Grgit 8 | import org.junit.After 9 | import org.junit.Before 10 | import org.junit.Test 11 | 12 | class CommitIdAbbrevPropertyTest { 13 | 14 | File projectDir 15 | Grgit repo 16 | 17 | @Before 18 | public void setUp() throws Exception { 19 | 20 | // Set up projectDir 21 | 22 | projectDir = File.createTempDir("BranchPropertyTest", ".tmp") 23 | GitRepositoryBuilder.setupProjectDir(projectDir, { gitRepoBuilder -> 24 | // empty repo 25 | }) 26 | 27 | // Set up repo 28 | repo = Grgit.open(dir: projectDir) 29 | } 30 | 31 | @After 32 | public void tearDown() throws Exception { 33 | repo?.close() 34 | projectDir.deleteDir() 35 | } 36 | 37 | @Test 38 | public void testDoCallOnEmptyRepo() { 39 | assertEquals('', new CommitIdAbbrevProperty().doCall(repo)) 40 | } 41 | 42 | @Test 43 | public void testDoCallOnOneCommit() { 44 | GitRepositoryBuilder.setupProjectDir(projectDir, { gitRepoBuilder -> 45 | // commit once 46 | gitRepoBuilder.commitFile("hello.txt", "Hello", "Added hello.txt") 47 | }) 48 | assertEquals(repo.head().abbreviatedId, new CommitIdAbbrevProperty().doCall(repo)) 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /src/test/groovy/com/gorylenko/properties/CommitIdDescribePropertyTest.groovy: -------------------------------------------------------------------------------- 1 | package com.gorylenko.properties 2 | 3 | import static org.junit.Assert.* 4 | 5 | import java.io.File 6 | import java.nio.file.Files 7 | import java.nio.file.StandardCopyOption 8 | 9 | import org.ajoberstar.grgit.Commit 10 | import org.ajoberstar.grgit.Grgit 11 | import org.junit.After 12 | import org.junit.Before 13 | import org.junit.Test 14 | 15 | class CommitIdDescribePropertyTest { 16 | 17 | File projectDir 18 | Grgit repo 19 | 20 | @Before 21 | public void setUp() throws Exception { 22 | 23 | // Set up projectDir 24 | 25 | projectDir = File.createTempDir("BranchPropertyTest", ".tmp") 26 | GitRepositoryBuilder.setupProjectDir(projectDir, { gitRepoBuilder -> 27 | // empty repo 28 | }) 29 | 30 | // Set up repo 31 | repo = Grgit.open(dir: projectDir) 32 | } 33 | 34 | @After 35 | public void tearDown() throws Exception { 36 | repo?.close() 37 | projectDir.deleteDir() 38 | } 39 | 40 | 41 | @Test 42 | public void testDoCallEmptyRepo() { 43 | assertEquals('', new CommitIdDescribeProperty().doCall(repo)) 44 | } 45 | 46 | @Test 47 | public void testDoCallNoTag() { 48 | Commit firstCommit 49 | GitRepositoryBuilder.setupProjectDir(projectDir, { gitRepoBuilder -> 50 | // commit 1 new file "hello.txt" 51 | firstCommit = gitRepoBuilder.commitFile("hello.txt", "Hello", "Added hello.txt") 52 | }) 53 | 54 | assertEquals('', new CommitIdDescribeProperty().doCall(repo)) 55 | } 56 | 57 | @Test 58 | public void testDoCallOnNoTagAndDirty() { 59 | 60 | GitRepositoryBuilder.setupProjectDir(projectDir, { gitRepoBuilder -> 61 | // commit 1 new file "hello.txt" 62 | gitRepoBuilder.commitFile("hello.txt", "Hello", "Added hello.txt") 63 | }) 64 | 65 | new File(projectDir, 'hello2.txt').text = 'Hello 2' 66 | 67 | assertEquals('', new CommitIdDescribeProperty().doCall(repo)) 68 | } 69 | 70 | @Test 71 | public void testDoCallOneTag() { 72 | 73 | GitRepositoryBuilder.setupProjectDir(projectDir, { gitRepoBuilder -> 74 | // commit 1 new file "hello.txt" 75 | gitRepoBuilder.commitFile("hello.txt", "Hello", "Added hello.txt") 76 | 77 | // add TAGONE to firstCommit (current HEAD) 78 | gitRepoBuilder.addTag("TAGONE") 79 | }) 80 | 81 | assertEquals("TAGONE", new CommitIdDescribeProperty().doCall(repo)) 82 | } 83 | 84 | @Test 85 | public void testDoCallOneTagDirty() { 86 | 87 | GitRepositoryBuilder.setupProjectDir(projectDir, { gitRepoBuilder -> 88 | // commit 1 new file "hello.txt" 89 | gitRepoBuilder.commitFile("hello.txt", "Hello", "Added hello.txt") 90 | 91 | // add TAGONE to firstCommit (current HEAD) 92 | gitRepoBuilder.addTag("TAGONE") 93 | new File(projectDir, 'hello2.txt').text = 'Hello 2' 94 | }) 95 | 96 | assertEquals("TAGONE-dirty", new CommitIdDescribeProperty().doCall(repo)) 97 | } 98 | 99 | @Test 100 | public void testDoCallOneTagOneCommit() { 101 | Commit secondCommit 102 | GitRepositoryBuilder.setupProjectDir(projectDir, { gitRepoBuilder -> 103 | // commit 1 new file "hello.txt" 104 | gitRepoBuilder.commitFile("hello.txt", "Hello", "Added hello.txt") 105 | 106 | // add TAGONE to firstCommit (current HEAD) 107 | gitRepoBuilder.addTag("TAGONE") 108 | secondCommit = gitRepoBuilder.commitFile("hello.txt", "Hello", "Added hello.txt") 109 | }) 110 | 111 | assertEquals("TAGONE-1-g" + secondCommit.abbreviatedId, new CommitIdDescribeProperty().doCall(repo)) 112 | } 113 | 114 | @Test 115 | public void testDoCallOneTagOneCommitDirty() { 116 | Commit secondCommit 117 | GitRepositoryBuilder.setupProjectDir(projectDir, { gitRepoBuilder -> 118 | // commit 1 new file "hello.txt" 119 | gitRepoBuilder.commitFile("hello.txt", "Hello", "Added hello.txt") 120 | 121 | // add TAGONE to firstCommit (current HEAD) 122 | gitRepoBuilder.addTag("TAGONE") 123 | secondCommit = gitRepoBuilder.commitFile("hello.txt", "Hello", "Added hello.txt") 124 | new File(projectDir, 'hello2.txt').text = 'Hello 2' 125 | }) 126 | 127 | assertEquals("TAGONE-1-g" + secondCommit.abbreviatedId + "-dirty", new CommitIdDescribeProperty().doCall(repo)) 128 | } 129 | 130 | @Test 131 | public void testDoCallOneTagOneCommitShallowClone() { 132 | 133 | File tmpDir = File.createTempDir("BranchPropertyTestShallowClone", ".tmp") 134 | Grgit repo1 = null 135 | 136 | try { 137 | InputStream is = CommitIdDescribePropertyTest.class.getResourceAsStream('/shallowclone3.zip') 138 | 139 | is.withStream { Files.copy(it, new File(tmpDir, "shallowclone3.zip").toPath(), StandardCopyOption.REPLACE_EXISTING) } 140 | 141 | AntBuilder ant = new AntBuilder(); 142 | 143 | ant.unzip(src: new File(tmpDir, "shallowclone3.zip") ,dest: tmpDir, overwrite:"true" ) 144 | 145 | repo1 = Grgit.open(dir: new File(tmpDir, "shallowclone3")) 146 | 147 | assertEquals("dc3a7d8", new CommitIdDescribeProperty().doCall(repo1)) 148 | 149 | } finally { 150 | repo1?.close() 151 | tmpDir.deleteDir() 152 | } 153 | 154 | } 155 | } 156 | -------------------------------------------------------------------------------- /src/test/groovy/com/gorylenko/properties/CommitIdPropertyTest.groovy: -------------------------------------------------------------------------------- 1 | package com.gorylenko.properties 2 | 3 | import static org.junit.Assert.* 4 | 5 | import java.io.File 6 | import org.ajoberstar.grgit.Commit 7 | import org.ajoberstar.grgit.Grgit 8 | import org.junit.After 9 | import org.junit.Before 10 | import org.junit.Test 11 | 12 | class CommitIdPropertyTest { 13 | 14 | File projectDir 15 | Grgit repo 16 | 17 | @Before 18 | public void setUp() throws Exception { 19 | 20 | // Set up projectDir 21 | 22 | projectDir = File.createTempDir("BranchPropertyTest", ".tmp") 23 | GitRepositoryBuilder.setupProjectDir(projectDir, { gitRepoBuilder -> 24 | // empty repo 25 | }) 26 | 27 | // Set up repo 28 | repo = Grgit.open(dir: projectDir) 29 | } 30 | 31 | @After 32 | public void tearDown() throws Exception { 33 | repo?.close() 34 | projectDir.deleteDir() 35 | } 36 | 37 | @Test 38 | public void testDoCallOnEmptyRepo() { 39 | assertEquals('', new CommitIdProperty().doCall(repo)) 40 | } 41 | 42 | @Test 43 | public void testDoCallOnOneCommit() { 44 | GitRepositoryBuilder.setupProjectDir(projectDir, { gitRepoBuilder -> 45 | // commit once 46 | gitRepoBuilder.commitFile("hello.txt", "Hello", "Added hello.txt") 47 | }) 48 | assertEquals(repo.head().id, new CommitIdProperty().doCall(repo)) 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /src/test/groovy/com/gorylenko/properties/CommitMessageFullPropertyTest.groovy: -------------------------------------------------------------------------------- 1 | package com.gorylenko.properties 2 | 3 | import static org.junit.Assert.* 4 | 5 | import java.io.File 6 | import org.ajoberstar.grgit.Commit 7 | import org.ajoberstar.grgit.Grgit 8 | import org.junit.After 9 | import org.junit.Before 10 | import org.junit.Test 11 | 12 | class CommitMessageFullPropertyTest { 13 | 14 | File projectDir 15 | Grgit repo 16 | 17 | @Before 18 | public void setUp() throws Exception { 19 | 20 | // Set up projectDir 21 | 22 | projectDir = File.createTempDir("BranchPropertyTest", ".tmp") 23 | GitRepositoryBuilder.setupProjectDir(projectDir, { gitRepoBuilder -> 24 | // empty repo 25 | }) 26 | 27 | // Set up repo 28 | repo = Grgit.open(dir: projectDir) 29 | } 30 | 31 | @After 32 | public void tearDown() throws Exception { 33 | repo?.close() 34 | projectDir.deleteDir() 35 | } 36 | 37 | @Test 38 | public void testDoCallOnEmptyRepo() { 39 | assertEquals('', new CommitMessageFullProperty().doCall(repo)) 40 | } 41 | 42 | @Test 43 | public void testDoCallOnOneCommit() { 44 | GitRepositoryBuilder.setupProjectDir(projectDir, { gitRepoBuilder -> 45 | // commit once 46 | gitRepoBuilder.commitFile("hello.txt", "Hello", "Added hello.txt\n\nSecond paragraph\n") 47 | }) 48 | assertEquals("Added hello.txt\n\nSecond paragraph\n", new CommitMessageFullProperty().doCall(repo)) 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /src/test/groovy/com/gorylenko/properties/CommitMessageShortPropertyTest.groovy: -------------------------------------------------------------------------------- 1 | package com.gorylenko.properties 2 | 3 | import static org.junit.Assert.* 4 | 5 | import java.io.File 6 | import org.ajoberstar.grgit.Commit 7 | import org.ajoberstar.grgit.Grgit 8 | import org.junit.After 9 | import org.junit.Before 10 | import org.junit.Test 11 | 12 | class CommitMessageShortPropertyTest { 13 | 14 | File projectDir 15 | Grgit repo 16 | 17 | @Before 18 | public void setUp() throws Exception { 19 | 20 | // Set up projectDir 21 | 22 | projectDir = File.createTempDir("BranchPropertyTest", ".tmp") 23 | GitRepositoryBuilder.setupProjectDir(projectDir, { gitRepoBuilder -> 24 | // empty repo 25 | }) 26 | 27 | // Set up repo 28 | repo = Grgit.open(dir: projectDir) 29 | } 30 | 31 | @After 32 | public void tearDown() throws Exception { 33 | repo?.close() 34 | projectDir.deleteDir() 35 | } 36 | 37 | @Test 38 | public void testDoCallOnEmptyRepo() { 39 | assertEquals('', new CommitMessageShortProperty().doCall(repo)) 40 | } 41 | 42 | @Test 43 | public void testDoCallOnOneCommit() { 44 | GitRepositoryBuilder.setupProjectDir(projectDir, { gitRepoBuilder -> 45 | // commit once 46 | gitRepoBuilder.commitFile("hello.txt", "Hello", "Added hello.txt\n\nSecond paragraph\n") 47 | }) 48 | assertEquals("Added hello.txt", new CommitMessageShortProperty().doCall(repo)) 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /src/test/groovy/com/gorylenko/properties/CommitTimePropertyTest.groovy: -------------------------------------------------------------------------------- 1 | package com.gorylenko.properties 2 | 3 | import static org.junit.Assert.* 4 | 5 | import java.io.File 6 | import java.text.SimpleDateFormat 7 | import org.ajoberstar.grgit.Commit 8 | import org.ajoberstar.grgit.Grgit 9 | import org.junit.After 10 | import org.junit.Before 11 | import org.junit.Test 12 | 13 | class CommitTimePropertyTest { 14 | 15 | File projectDir 16 | Grgit repo 17 | 18 | @Before 19 | public void setUp() throws Exception { 20 | 21 | // Set up projectDir 22 | 23 | projectDir = File.createTempDir("BranchPropertyTest", ".tmp") 24 | GitRepositoryBuilder.setupProjectDir(projectDir, { gitRepoBuilder -> 25 | // empty git repo 26 | }) 27 | 28 | // Set up repo 29 | repo = Grgit.open(dir: projectDir) 30 | 31 | } 32 | 33 | @After 34 | public void tearDown() throws Exception { 35 | repo?.close() 36 | projectDir.deleteDir() 37 | } 38 | 39 | @Test 40 | public void testDoCallOnEmptyRepo() { 41 | assertEquals('', new CommitTimeProperty(null, null).doCall(repo)) 42 | } 43 | 44 | @Test 45 | public void testDoCallOneCommit() { 46 | 47 | Commit firstCommit 48 | GitRepositoryBuilder.setupProjectDir(projectDir, { gitRepoBuilder -> 49 | // commit 1 new file "hello.txt" 50 | firstCommit = gitRepoBuilder.commitFile("hello.txt", "Hello", "Added hello.txt") 51 | }) 52 | 53 | assertEquals(firstCommit.dateTime.toInstant().epochSecond.toString(), new CommitTimeProperty(null, null).doCall(repo)) 54 | } 55 | 56 | @Test 57 | public void testDoCallWithFormat() { 58 | 59 | Commit firstCommit 60 | GitRepositoryBuilder.setupProjectDir(projectDir, { gitRepoBuilder -> 61 | // commit 1 new file "hello.txt" 62 | firstCommit = gitRepoBuilder.commitFile("hello.txt", "Hello", "Added hello.txt") 63 | }) 64 | 65 | SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mmZ") 66 | sdf.setTimeZone(TimeZone.getTimeZone("PST")) 67 | String date = sdf.format(Date.from(firstCommit.dateTime.toInstant())) 68 | 69 | assertEquals(date, new CommitTimeProperty("yyyy-MM-dd'T'HH:mmZ", "PST").doCall(repo)) 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/test/groovy/com/gorylenko/properties/CommitUserEmailPropertyTest.groovy: -------------------------------------------------------------------------------- 1 | package com.gorylenko.properties 2 | 3 | import static org.junit.Assert.* 4 | 5 | import java.io.File 6 | import org.ajoberstar.grgit.Commit 7 | import org.ajoberstar.grgit.Grgit 8 | import org.junit.After 9 | import org.junit.Before 10 | import org.junit.Test 11 | 12 | class CommitUserEmailPropertyTest { 13 | 14 | File projectDir 15 | Grgit repo 16 | 17 | @Before 18 | public void setUp() throws Exception { 19 | 20 | // Set up projectDir 21 | 22 | projectDir = File.createTempDir("BranchPropertyTest", ".tmp") 23 | GitRepositoryBuilder.setupProjectDir(projectDir, { gitRepoBuilder -> 24 | // empty repo 25 | }) 26 | 27 | // Set up repo 28 | repo = Grgit.open(dir: projectDir) 29 | } 30 | 31 | @After 32 | public void tearDown() throws Exception { 33 | repo?.close() 34 | projectDir.deleteDir() 35 | } 36 | 37 | @Test 38 | public void testDoCallOnEmptyRepo() { 39 | assertEquals('', new CommitUserEmailProperty().doCall(repo)) 40 | } 41 | 42 | @Test 43 | public void testDoCallOnOneCommit() { 44 | GitRepositoryBuilder.setupProjectDir(projectDir, { gitRepoBuilder -> 45 | // commit once 46 | gitRepoBuilder.commitFile("hello.txt", "Hello", "Added hello.txt") 47 | }) 48 | assertEquals(repo.head().author.email, new CommitUserEmailProperty().doCall(repo)) 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /src/test/groovy/com/gorylenko/properties/CommitUserNamePropertyTest.groovy: -------------------------------------------------------------------------------- 1 | package com.gorylenko.properties 2 | 3 | import static org.junit.Assert.* 4 | 5 | import java.io.File 6 | import org.ajoberstar.grgit.Commit 7 | import org.ajoberstar.grgit.Grgit 8 | import org.junit.After 9 | import org.junit.Before 10 | import org.junit.Test 11 | 12 | class CommitUserNamePropertyTest { 13 | 14 | File projectDir 15 | Grgit repo 16 | 17 | @Before 18 | public void setUp() throws Exception { 19 | 20 | // Set up projectDir 21 | 22 | projectDir = File.createTempDir("BranchPropertyTest", ".tmp") 23 | GitRepositoryBuilder.setupProjectDir(projectDir, { gitRepoBuilder -> 24 | // empty repo 25 | }) 26 | 27 | // Set up repo 28 | repo = Grgit.open(dir: projectDir) 29 | } 30 | 31 | @After 32 | public void tearDown() throws Exception { 33 | repo?.close() 34 | projectDir.deleteDir() 35 | } 36 | 37 | @Test 38 | public void testDoCallOnEmptyRepo() { 39 | assertEquals('', new CommitUserNameProperty().doCall(repo)) 40 | } 41 | 42 | @Test 43 | public void testDoCallOnOneCommit() { 44 | GitRepositoryBuilder.setupProjectDir(projectDir, { gitRepoBuilder -> 45 | // commit once 46 | gitRepoBuilder.commitFile("hello.txt", "Hello", "Added hello.txt") 47 | }) 48 | assertEquals(repo.head().author.name, new CommitUserNameProperty().doCall(repo)) 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /src/test/groovy/com/gorylenko/properties/DirtyPropertyTest.groovy: -------------------------------------------------------------------------------- 1 | package com.gorylenko.properties 2 | 3 | import static org.junit.Assert.* 4 | 5 | import java.io.File 6 | import org.ajoberstar.grgit.Commit 7 | import org.ajoberstar.grgit.Grgit 8 | import org.junit.After 9 | import org.junit.Before 10 | import org.junit.Test 11 | 12 | class DirtyPropertyTest { 13 | 14 | File projectDir 15 | Grgit repo 16 | 17 | @Before 18 | public void setUp() throws Exception { 19 | 20 | // Set up projectDir 21 | 22 | projectDir = File.createTempDir("BranchPropertyTest", ".tmp") 23 | GitRepositoryBuilder.setupProjectDir(projectDir, { gitRepoBuilder -> 24 | // empty repo 25 | }) 26 | 27 | // Set up repo 28 | repo = Grgit.open(dir: projectDir) 29 | } 30 | 31 | @After 32 | public void tearDown() throws Exception { 33 | repo?.close() 34 | projectDir.deleteDir() 35 | } 36 | 37 | @Test 38 | public void testDoCallOnEmptyRepo() { 39 | assertEquals('false', new DirtyProperty().doCall(repo)) 40 | } 41 | 42 | @Test 43 | public void testDoCallOnEmptyRepoDirty() { 44 | new File(projectDir, 'hello2.txt').text = 'Hello 2' 45 | assertEquals('true', new DirtyProperty().doCall(repo)) 46 | } 47 | 48 | @Test 49 | public void testDoCallOnOneCommit() { 50 | GitRepositoryBuilder.setupProjectDir(projectDir, { gitRepoBuilder -> 51 | // commit once 52 | gitRepoBuilder.commitFile("hello.txt", "Hello", "Added hello.txt") 53 | }) 54 | assertEquals('false', new DirtyProperty().doCall(repo)) 55 | } 56 | 57 | 58 | @Test 59 | public void testDoCallOnOneCommitDirty() { 60 | GitRepositoryBuilder.setupProjectDir(projectDir, { gitRepoBuilder -> 61 | // commit once 62 | gitRepoBuilder.commitFile("hello.txt", "Hello", "Added hello.txt") 63 | }) 64 | new File(projectDir, 'hello2.txt').text = 'Hello 2' 65 | assertEquals('true', new DirtyProperty().doCall(repo)) 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/test/groovy/com/gorylenko/properties/GitRepositoryBuilder.groovy: -------------------------------------------------------------------------------- 1 | package com.gorylenko.properties 2 | 3 | import java.io.File 4 | import org.ajoberstar.grgit.Commit 5 | import org.ajoberstar.grgit.Grgit 6 | import org.ajoberstar.grgit.Person 7 | 8 | import groovy.lang.Closure 9 | 10 | class GitRepositoryBuilder implements AutoCloseable { 11 | private File workingDirectory 12 | private Grgit grgit 13 | 14 | Person user = new Person('testuser', 'testuser@example.com') 15 | 16 | GitRepositoryBuilder(File workingDirectory) { 17 | 18 | this.workingDirectory = workingDirectory 19 | if (new File(workingDirectory, '.git').exists()) { 20 | this.grgit = Grgit.open(dir: workingDirectory) 21 | } else { 22 | this.grgit = Grgit.init(dir: workingDirectory) 23 | } 24 | 25 | } 26 | 27 | Commit commitFile(String name, String content, String message) { 28 | new File(workingDirectory, name).text = content 29 | grgit.add(patterns: [name]) 30 | Commit commit = grgit.commit(message: message, author: user, committer: user) 31 | return commit 32 | } 33 | 34 | void addBranch(String name) { 35 | grgit.branch.add(name: name) 36 | } 37 | 38 | void addTag(String name) { 39 | grgit.tag.add (name: name) 40 | } 41 | 42 | void addBranchAndCheckout(String name) { 43 | grgit.checkout(branch: name, createBranch: true) 44 | } 45 | 46 | void setConfigString(final String section, final String subsection, final String name, final String value) { 47 | grgit.repository.jgit.repository.config.setString(section, subsection, name, value) 48 | grgit.repository.jgit.repository.config.save() 49 | } 50 | 51 | void close() { 52 | grgit?.close() 53 | } 54 | 55 | static void setupProjectDir(File projectDir, Closure closure, GitRepositoryBuilder builder = null) { 56 | GitRepositoryBuilder gitRepoBuilder = builder ?: new GitRepositoryBuilder(projectDir) 57 | try { 58 | closure(gitRepoBuilder) 59 | } finally { 60 | gitRepoBuilder.close() 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/test/groovy/com/gorylenko/properties/RemoteOriginUrlPropertyTest.groovy: -------------------------------------------------------------------------------- 1 | package com.gorylenko.properties 2 | 3 | import static org.junit.Assert.* 4 | 5 | import java.io.File 6 | import java.text.SimpleDateFormat 7 | import org.ajoberstar.grgit.Commit 8 | import org.ajoberstar.grgit.Grgit 9 | import org.junit.After 10 | import org.junit.Before 11 | import org.junit.Test 12 | 13 | class RemoteOriginUrlPropertyTest { 14 | 15 | File projectDir 16 | Commit firstCommit 17 | Grgit repo 18 | 19 | @Before 20 | public void setUp() throws Exception { 21 | 22 | // Set up projectDir 23 | 24 | projectDir = File.createTempDir("BranchPropertyTest", ".tmp") 25 | GitRepositoryBuilder.setupProjectDir(projectDir, { gitRepoBuilder -> 26 | // commit 1 new file "hello.txt" 27 | firstCommit = gitRepoBuilder.commitFile("hello.txt", "Hello", "Added hello.txt") 28 | }) 29 | 30 | // Set up repo 31 | repo = Grgit.open(dir: projectDir) 32 | 33 | } 34 | 35 | @After 36 | public void tearDown() throws Exception { 37 | repo?.close() 38 | projectDir.deleteDir() 39 | } 40 | 41 | @Test 42 | public void testDoCall() { 43 | assertEquals('', new RemoteOriginUrlProperty().doCall(repo)) 44 | } 45 | 46 | 47 | @Test 48 | public void testDoCallWithRemoteUrl() { 49 | GitRepositoryBuilder.setupProjectDir(projectDir, { gitRepoBuilder -> 50 | gitRepoBuilder.setConfigString("remote", "origin", "url", "git@github.com:n0mer/gradle-git-properties.git") 51 | }) 52 | def repo1 = Grgit.open(dir: projectDir) 53 | 54 | assertEquals('git@github.com:n0mer/gradle-git-properties.git', new RemoteOriginUrlProperty().doCall(repo)) 55 | repo1.close() 56 | } 57 | 58 | @Test 59 | public void testDoCallWithRemoteUrlHavingPassword() { 60 | GitRepositoryBuilder.setupProjectDir(projectDir, { gitRepoBuilder -> 61 | gitRepoBuilder.setConfigString("remote", "origin", "url", "https://user:password@myprivate.git.host/gitrepo.git") 62 | }) 63 | def repo1 = Grgit.open(dir: projectDir) 64 | 65 | assertEquals('https://myprivate.git.host/gitrepo.git', new RemoteOriginUrlProperty().doCall(repo)) 66 | repo1.close() 67 | } 68 | 69 | @Test 70 | public void testDoCallWithRemoteUrlWithoutPassword() { 71 | GitRepositoryBuilder.setupProjectDir(projectDir, { gitRepoBuilder -> 72 | gitRepoBuilder.setConfigString("remote", "origin", "url", "https://myprivate.git.host/gitrepo.git") 73 | }) 74 | def repo1 = Grgit.open(dir: projectDir) 75 | 76 | assertEquals('https://myprivate.git.host/gitrepo.git', new RemoteOriginUrlProperty().doCall(repo)) 77 | repo1.close() 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /src/test/groovy/com/gorylenko/properties/TagsPropertyTest.groovy: -------------------------------------------------------------------------------- 1 | package com.gorylenko.properties 2 | 3 | import static org.junit.Assert.* 4 | 5 | import java.io.File 6 | import java.text.SimpleDateFormat 7 | import org.ajoberstar.grgit.Commit 8 | import org.ajoberstar.grgit.Grgit 9 | import org.junit.After 10 | import org.junit.Before 11 | import org.junit.Test 12 | 13 | class TagsPropertyTest { 14 | 15 | File projectDir 16 | Grgit repo 17 | 18 | @Before 19 | public void setUp() throws Exception { 20 | 21 | // Set up projectDir 22 | 23 | projectDir = File.createTempDir("BranchPropertyTest", ".tmp") 24 | GitRepositoryBuilder.setupProjectDir(projectDir, { gitRepoBuilder -> 25 | // empty repo 26 | }) 27 | // Set up repo 28 | repo = Grgit.open(dir: projectDir) 29 | 30 | } 31 | 32 | @After 33 | public void tearDown() throws Exception { 34 | repo?.close() 35 | projectDir.deleteDir() 36 | } 37 | 38 | @Test 39 | public void testDoCallOnEmptyRepo() { 40 | assertEquals('', new TagsProperty().doCall(repo)) 41 | } 42 | 43 | @Test 44 | public void testDoCallOneCommit() { 45 | GitRepositoryBuilder.setupProjectDir(projectDir, { gitRepoBuilder -> 46 | // commit 1 new file "hello.txt" 47 | gitRepoBuilder.commitFile("hello.txt", "Hello", "Added hello.txt") 48 | }) 49 | assertEquals('', new TagsProperty().doCall(repo)) 50 | } 51 | 52 | @Test 53 | public void testDoCallWithOneTag() { 54 | GitRepositoryBuilder.setupProjectDir(projectDir, { gitRepoBuilder -> 55 | // commit 1 new file "hello.txt" 56 | gitRepoBuilder.commitFile("hello.txt", "Hello", "Added hello.txt") 57 | gitRepoBuilder.addTag("TAG-1") 58 | }) 59 | assertEquals('TAG-1', new TagsProperty().doCall(repo)) 60 | } 61 | 62 | 63 | @Test 64 | public void testDoCallWith2Tags() { 65 | GitRepositoryBuilder.setupProjectDir(projectDir, { gitRepoBuilder -> 66 | // commit 1 new file "hello.txt" 67 | gitRepoBuilder.commitFile("hello.txt", "Hello", "Added hello.txt") 68 | gitRepoBuilder.addTag("TAG-1") 69 | gitRepoBuilder.addTag("TAG-2") 70 | }) 71 | assertEquals('TAG-1,TAG-2', new TagsProperty().doCall(repo)) 72 | } 73 | 74 | @Test 75 | public void testDoCallWithNotCurrentTag() { 76 | GitRepositoryBuilder.setupProjectDir(projectDir, { gitRepoBuilder -> 77 | // commit 1 new file "hello.txt" 78 | gitRepoBuilder.commitFile("hello.txt", "Hello", "Added hello.txt") 79 | gitRepoBuilder.addTag("TAG-1") 80 | gitRepoBuilder.commitFile("hello2.txt", "Hello2", "Added hello2.txt") 81 | }) 82 | assertEquals('', new TagsProperty().doCall(repo)) 83 | } 84 | 85 | } 86 | -------------------------------------------------------------------------------- /src/test/groovy/com/gorylenko/properties/TotalCommitCountPropertyTest.groovy: -------------------------------------------------------------------------------- 1 | package com.gorylenko.properties 2 | 3 | import static org.junit.Assert.* 4 | 5 | import java.io.File 6 | import org.ajoberstar.grgit.Commit 7 | import org.ajoberstar.grgit.Grgit 8 | import org.junit.After 9 | import org.junit.Before 10 | import org.junit.Test 11 | 12 | class TotalCommitCountPropertyTest { 13 | 14 | File projectDir 15 | Grgit repo 16 | 17 | @Before 18 | public void setUp() throws Exception { 19 | 20 | // Set up projectDir 21 | 22 | projectDir = File.createTempDir("BranchPropertyTest", ".tmp") 23 | GitRepositoryBuilder.setupProjectDir(projectDir, { gitRepoBuilder -> 24 | // empty git repo 25 | }) 26 | 27 | // Set up repo 28 | repo = Grgit.open(dir: projectDir) 29 | } 30 | 31 | private TotalCommitCountProperty createTarget() { 32 | new TotalCommitCountProperty(new CacheSupport()) 33 | } 34 | 35 | @After 36 | public void tearDown() throws Exception { 37 | repo?.close() 38 | projectDir.deleteDir() 39 | } 40 | 41 | @Test 42 | public void testDoCallOnEmptyRepo() { 43 | 44 | assertEquals('0', createTarget().doCall(repo)) 45 | } 46 | 47 | @Test 48 | public void testDoCallOneCommit() { 49 | 50 | GitRepositoryBuilder.setupProjectDir(projectDir, { gitRepoBuilder -> 51 | gitRepoBuilder.commitFile("hello.txt", "Hello", "Added hello.txt") 52 | }) 53 | 54 | assertEquals("1", createTarget().doCall(repo)) 55 | } 56 | 57 | @Test 58 | public void testDoCallTwoCommits() { 59 | 60 | GitRepositoryBuilder.setupProjectDir(projectDir, { gitRepoBuilder -> 61 | gitRepoBuilder.commitFile("hello.txt", "Hello", "Added hello.txt") 62 | gitRepoBuilder.commitFile("hello2.txt", "Hello2", "Added hello2.txt") 63 | }) 64 | 65 | assertEquals("2", createTarget().doCall(repo)) 66 | } 67 | 68 | @Test 69 | public void testDoCallTwoCommitsNewBranchThenThirdCommit() { 70 | 71 | GitRepositoryBuilder.setupProjectDir(projectDir, { gitRepoBuilder -> 72 | gitRepoBuilder.commitFile("hello.txt", "Hello", "Added hello.txt") 73 | gitRepoBuilder.commitFile("hello2.txt", "Hello2", "Added hello2.txt") 74 | gitRepoBuilder.addBranchAndCheckout("my-branch") 75 | gitRepoBuilder.commitFile("hello3.txt", "Hello3", "Added hello3.txt") 76 | }) 77 | 78 | assertEquals("3", createTarget().doCall(repo)) 79 | } 80 | 81 | } 82 | -------------------------------------------------------------------------------- /src/test/groovy/com/gorylenko/writer/NormalizeEOLOutputStreamTest.groovy: -------------------------------------------------------------------------------- 1 | package com.gorylenko.writer 2 | 3 | import org.junit.Before 4 | import org.junit.Test 5 | import static org.junit.Assert.* 6 | 7 | 8 | public class NormalizeEOLOutputStreamTest { 9 | ByteArrayOutputStream b 10 | NormalizeEOLOutputStream s 11 | OutputStreamWriter w 12 | 13 | @Before 14 | public void setUp() throws Exception { 15 | b = new ByteArrayOutputStream() 16 | s = new NormalizeEOLOutputStream(b) 17 | w = new OutputStreamWriter(s, "8859_1") 18 | } 19 | 20 | @Test 21 | public void testNormarlizeCRLF() { 22 | try { 23 | w.write("line1\r\nline2\r\n\r\n") 24 | } finally { 25 | w.close() 26 | } 27 | assertEquals("line1\nline2\n\n", new String(b.toByteArray(), "8859_1")) 28 | } 29 | 30 | @Test 31 | public void testNormarlizeCR() { 32 | try { 33 | w.write("line1\rline2\r\r") 34 | } finally { 35 | w.close() 36 | } 37 | assertEquals("line1\nline2\n\n", new String(b.toByteArray(), "8859_1")) 38 | } 39 | 40 | @Test 41 | public void testNormarlizeLF() { 42 | try { 43 | w.write("line1\nline2\n\n") 44 | } finally { 45 | w.close() 46 | } 47 | assertEquals("line1\nline2\n\n", new String(b.toByteArray(), "8859_1")) 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/test/groovy/com/gorylenko/writer/SkipPropertiesCommentsOutputStreamTest.groovy: -------------------------------------------------------------------------------- 1 | package com.gorylenko.writer 2 | 3 | import org.junit.Before 4 | import org.junit.Test 5 | import static org.junit.Assert.* 6 | 7 | 8 | public class SkipPropertiesCommentsOutputStreamTest { 9 | ByteArrayOutputStream b 10 | SkipPropertiesCommentsOutputStream s 11 | OutputStreamWriter w 12 | 13 | @Before 14 | public void setUp() throws Exception { 15 | b = new ByteArrayOutputStream() 16 | s = new SkipPropertiesCommentsOutputStream(b) 17 | w = new OutputStreamWriter(s, "8859_1") 18 | } 19 | 20 | @Test 21 | public void test0Comment() { 22 | try { 23 | w.write("line1\nline2\n\n") 24 | } finally { 25 | w.close() 26 | } 27 | assertEquals("line1\nline2\n\n", new String(b.toByteArray(), "8859_1")) 28 | } 29 | @Test 30 | public void test0CommentWithSpecialChar() { 31 | try { 32 | w.write("line1#withspecialchars!\n\n") 33 | } finally { 34 | w.close() 35 | } 36 | assertEquals("line1#withspecialchars!\n\n", new String(b.toByteArray(), "8859_1")) 37 | } 38 | @Test 39 | public void test1Comment1() { 40 | try { 41 | w.write("#line1\nline2\n\n") 42 | } finally { 43 | w.close() 44 | } 45 | assertEquals("line2\n\n", new String(b.toByteArray(), "8859_1")) 46 | } 47 | @Test 48 | public void test1Comment2() { 49 | try { 50 | w.write("!line1\nline2\n\n") 51 | } finally { 52 | w.close() 53 | } 54 | assertEquals("line2\n\n", new String(b.toByteArray(), "8859_1")) 55 | } 56 | @Test 57 | public void test2Comments1() { 58 | try { 59 | w.write("##line1\n#line2\nline3\n\n") 60 | } finally { 61 | w.close() 62 | } 63 | assertEquals("line3\n\n", new String(b.toByteArray(), "8859_1")) 64 | } 65 | @Test 66 | public void test2Comments2() { 67 | try { 68 | w.write("!!line1\n!line2\nline3\n\n") 69 | } finally { 70 | w.close() 71 | } 72 | assertEquals("line3\n\n", new String(b.toByteArray(), "8859_1")) 73 | } 74 | 75 | } 76 | -------------------------------------------------------------------------------- /src/test/resources/shallowclone3.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/n0mer/gradle-git-properties/d818a2765238cb52109d32851dad311139da62ed/src/test/resources/shallowclone3.zip --------------------------------------------------------------------------------