From 1c34b4bc5153b1f3418df21fe8322abbf183d187 Mon Sep 17 00:00:00 2001 From: Gareth Coles Date: Wed, 26 Jun 2024 19:38:10 +0100 Subject: [PATCH 1/2] XML-style headers, Kotlin, extra patterns --- .gitattributes | 1 + build.gradle.kts | 21 +++-- .../api/comment/HeaderCommentManager.java | 44 ++++++++- .../api/comment/XmlStyleHeaderComment.kt | 74 +++++++++++++++ .../test/comment/XmlStyleHeaderCommentTest.kt | 92 +++++++++++++++++++ 5 files changed, 224 insertions(+), 8 deletions(-) create mode 100644 src/main/java/dev/yumi/gradle/licenser/api/comment/XmlStyleHeaderComment.kt create mode 100644 src/test/java/dev/yumi/gradle/licenser/test/comment/XmlStyleHeaderCommentTest.kt diff --git a/.gitattributes b/.gitattributes index 66cc64a..1a33558 100644 --- a/.gitattributes +++ b/.gitattributes @@ -16,4 +16,5 @@ *.war binary # Custom +src/functionalTest/resources/scenarios/**/* text eol=lf src/functionalTest/resources/scenarios/base_java/src/main/java/test/TestClassCrlf*.java text eol=crlf diff --git a/build.gradle.kts b/build.gradle.kts index 33cff50..dc4ced5 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,12 +1,15 @@ plugins { - id("dev.yumi.gradle.licenser").version("1.1.+") - id("com.gradle.plugin-publish").version("1.2.0") - id("maven-publish") - id("signing") + id("dev.yumi.gradle.licenser") version "1.1.+" + id("com.gradle.plugin-publish") version "1.2.0" + + kotlin("jvm") version "1.9.24" + + `maven-publish` + signing } group = "dev.yumi" -version = "1.1.2" +version = "1.1.3" val javaVersion = 17 repositories { @@ -33,7 +36,8 @@ gradlePlugin { create("yumi_gradle_licenser") { id = "dev.yumi.gradle.licenser" displayName = "Yumi Gradle Licenser" - description = "A plugin to automatically manage license headers in project files, designed to be flexible to easily support many use cases like having different header kinds for different files." + description = + "A plugin to automatically manage license headers in project files, designed to be flexible to easily support many use cases like having different header kinds for different files." tags = listOf("licenser", "licensing", "licenses", "license-header") implementationClass = "dev.yumi.gradle.licenser.YumiLicenserGradlePlugin" } @@ -53,6 +57,11 @@ java { testResultsDir.set(layout.buildDirectory.dir("junit-xml")) } +kotlin { + // Require explicit visibility/type definitions for public types, among other things + explicitApi() +} + tasks.withType().configureEach { options.encoding = "UTF-8" options.isDeprecation = true diff --git a/src/main/java/dev/yumi/gradle/licenser/api/comment/HeaderCommentManager.java b/src/main/java/dev/yumi/gradle/licenser/api/comment/HeaderCommentManager.java index 79ff161..27fb3f9 100644 --- a/src/main/java/dev/yumi/gradle/licenser/api/comment/HeaderCommentManager.java +++ b/src/main/java/dev/yumi/gradle/licenser/api/comment/HeaderCommentManager.java @@ -29,25 +29,65 @@ public class HeaderCommentManager { public HeaderCommentManager() { this.register(new PatternSet() .include( + // C/++ "**/*.c", "**/*.cpp", "**/*.cxx", "**/*.h", "**/*.hpp", "**/*.hxx", + + // Java "**/*.java", + + // Kotlin "**/*.kt", "**/*.kts", - "**/*.scala" + + // Scala + "**/*.scala", + + // Web languages + "**/*.dart", // Dart language + "**/*.js", // JavaScript + "**/*.jsx", // JavaScript XML + "**/*.ts", // TypeScript + "**/*.tsx", // TypeScript XML + + // Stylesheets + "**/*.css", // CSS stylesheets + "**/*.less", // Less (Extended CSS) + "**/*.scss", // SCSS (CSS syntax for SASS) + "**/*.styl" // Stylus (Alternative CSS syntax) ), CStyleHeaderComment.INSTANCE ); + + this.register(new PatternSet() + .include( + // Web markup + "**/*.htm", + "**/*.html", + "**/*.xhtml", + + // Extended HTML + "**/*.svelte", + "**/*.vue", + + // Data formats + "**/*.xml", + + // Image formats + "**/*.svg" + ), + XmlStyleHeaderComment.INSTANCE + ); } /** * Registers a header comment implementation for a given file pattern. * - * @param filePattern the file pattern to match files for which the given header comment implementation applies + * @param filePattern the file pattern to match files for which the given header comment implementation applies * @param headerComment the header comment implementation */ public void register(@NotNull PatternSet filePattern, @NotNull HeaderComment headerComment) { diff --git a/src/main/java/dev/yumi/gradle/licenser/api/comment/XmlStyleHeaderComment.kt b/src/main/java/dev/yumi/gradle/licenser/api/comment/XmlStyleHeaderComment.kt new file mode 100644 index 0000000..7ddb5a0 --- /dev/null +++ b/src/main/java/dev/yumi/gradle/licenser/api/comment/XmlStyleHeaderComment.kt @@ -0,0 +1,74 @@ +/* + * Copyright 2023 Yumi Project + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ + +package dev.yumi.gradle.licenser.api.comment + +private const val COMMENT_START = "" + +/** + * [HeaderComment] implementation for XML-style comments. + * + * @author gdude2002 + * @since 1.1.3 + */ +public open class XmlStyleHeaderComment protected constructor() : HeaderComment { + override fun readHeaderComment(source: String): HeaderComment.Result { + val separator = this.extractLineSeparator(source) + + // Find the first comment block using a blank line + val firstBlock = source.split(separator.repeat(2)).first() + + // Find the start of the comment by its opening characters + val start = firstBlock.indexOf(COMMENT_START) + + if (start != 0) { // If the comment doesn't open on the first character of the block... + // ...check whether all prefixing characters are spaces. + val allWhitespacePrefixed = (0 until start).all { source[it] in arrayOf(' ', separator) } + + if (!allWhitespacePrefixed) { // If not, this isn't a licence header – bail out. + return HeaderComment.Result(0, 0, null, separator) + } + } + + // Find the last character of the comment, including the closing characters. + val end = firstBlock.indexOf(COMMENT_END) + COMMENT_END.length + + if (start < 0 || end < 0) { + // If we can't find the start or end of the block, there's no licence header – bail out. + return HeaderComment.Result(0, 0, null, separator) + } + + // Grab the licence header comment, and split it into lines. + val result: MutableList = source.substring(start, end).split(separator).toMutableList() + + // Remove the first and last lines, as those are simply comment start/end characters, and not the licence text. + result.removeFirst() + result.removeLast() + + // Remove any indents from the licence header text, and return the result. + return HeaderComment.Result(start, end, result.map { it.trimIndent() }, separator) + } + + override fun writeHeaderComment(header: List, separator: String): String = + buildString { // Use a string builder to generate the licence header. + append("$COMMENT_START$separator") + + header.forEach { + append("\t$it$separator") + } + + append(COMMENT_END) + } + + public companion object { + /** Instance of this header comment type. **/ + @JvmField // Otherwise this would be `XmlStyleHeaderComment.Companion.getINSTANCE` + public val INSTANCE: XmlStyleHeaderComment = XmlStyleHeaderComment() + } +} diff --git a/src/test/java/dev/yumi/gradle/licenser/test/comment/XmlStyleHeaderCommentTest.kt b/src/test/java/dev/yumi/gradle/licenser/test/comment/XmlStyleHeaderCommentTest.kt new file mode 100644 index 0000000..ba8da49 --- /dev/null +++ b/src/test/java/dev/yumi/gradle/licenser/test/comment/XmlStyleHeaderCommentTest.kt @@ -0,0 +1,92 @@ +/* + * Copyright 2023 Yumi Project + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ + +package dev.yumi.gradle.licenser.test.comment + +import dev.yumi.gradle.licenser.api.comment.XmlStyleHeaderComment +import org.junit.jupiter.api.Assertions.* +import org.junit.jupiter.api.Test + +class XmlStyleHeaderCommentTest { + @Test + fun `Parsing with existing header`() { + val result = XmlStyleHeaderComment.INSTANCE.readHeaderComment( + """ + + + + + + + + + + + + + + + + """.trimIndent() + + val result = XmlStyleHeaderComment.INSTANCE.writeHeaderComment( + listOf( + "Sample License Header", + "", + "Yippee", + ), + + "\n" + ) + + assertEquals(expected, result) + } +} From 48f54129fa0e5e30fa34a58fc93711860c61e2b2 Mon Sep 17 00:00:00 2001 From: Gareth Coles Date: Wed, 26 Jun 2024 22:21:45 +0100 Subject: [PATCH 2/2] Apply generated headers, address review --- build.gradle.kts | 2 +- .../yumi/gradle/licenser/api/comment/XmlStyleHeaderComment.kt | 4 ++-- .../gradle/licenser/test/comment/XmlStyleHeaderCommentTest.kt | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index dc4ced5..2d0c685 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -9,7 +9,7 @@ plugins { } group = "dev.yumi" -version = "1.1.3" +version = "1.2.0" val javaVersion = 17 repositories { diff --git a/src/main/java/dev/yumi/gradle/licenser/api/comment/XmlStyleHeaderComment.kt b/src/main/java/dev/yumi/gradle/licenser/api/comment/XmlStyleHeaderComment.kt index 7ddb5a0..cb1487e 100644 --- a/src/main/java/dev/yumi/gradle/licenser/api/comment/XmlStyleHeaderComment.kt +++ b/src/main/java/dev/yumi/gradle/licenser/api/comment/XmlStyleHeaderComment.kt @@ -1,5 +1,5 @@ /* - * Copyright 2023 Yumi Project + * Copyright 2024 Yumi Project * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this @@ -15,7 +15,7 @@ private const val COMMENT_END = "-->" * [HeaderComment] implementation for XML-style comments. * * @author gdude2002 - * @since 1.1.3 + * @since 1.2.0 */ public open class XmlStyleHeaderComment protected constructor() : HeaderComment { override fun readHeaderComment(source: String): HeaderComment.Result { diff --git a/src/test/java/dev/yumi/gradle/licenser/test/comment/XmlStyleHeaderCommentTest.kt b/src/test/java/dev/yumi/gradle/licenser/test/comment/XmlStyleHeaderCommentTest.kt index ba8da49..470dfbf 100644 --- a/src/test/java/dev/yumi/gradle/licenser/test/comment/XmlStyleHeaderCommentTest.kt +++ b/src/test/java/dev/yumi/gradle/licenser/test/comment/XmlStyleHeaderCommentTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2023 Yumi Project + * Copyright 2024 Yumi Project * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this