[PowerAssert] Add Gradle build tools integration tests for Power-Assert
The integration test project was copied from the sample project in github.com/bnorm/kotlin-power-assert. Original license information has been preserved even though commit history has not been. ^KT-65951 Fixed
This commit is contained in:
+1
@@ -43,6 +43,7 @@ class PluginsDslIT : KGPBaseTest() {
|
||||
"org.jetbrains.kotlin.noarg.gradle.KotlinJpaSubplugin",
|
||||
"org.jetbrains.kotlinx.atomicfu.gradle.AtomicfuKotlinGradleSubplugin",
|
||||
"org.jetbrains.kotlin.lombok.gradle.LombokSubplugin",
|
||||
"org.jetbrains.kotlin.powerassert.gradle.PowerAssertGradlePlugin",
|
||||
"org.jetbrains.kotlin.samWithReceiver.gradle.SamWithReceiverGradleSubplugin",
|
||||
"org.jetbrains.kotlinx.serialization.gradle.SerializationGradleSubplugin"
|
||||
)
|
||||
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.gradle
|
||||
|
||||
import org.gradle.util.GradleVersion
|
||||
import org.jetbrains.kotlin.gradle.testbase.*
|
||||
import org.junit.jupiter.api.DisplayName
|
||||
|
||||
@DisplayName("Power-Assert tests")
|
||||
class PowerAssertIT : KGPBaseTest() {
|
||||
|
||||
@OtherGradlePluginTests
|
||||
@DisplayName("power-assert works")
|
||||
@GradleTest
|
||||
fun testPowerAssertSimple(gradleVersion: GradleVersion) {
|
||||
project("powerAssertSimple", gradleVersion) {
|
||||
build("check")
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
@@ -33,6 +33,7 @@ internal val DEFAULT_GROOVY_SETTINGS_FILE =
|
||||
id "org.jetbrains.kotlin.plugin.jpa" version "${'$'}kotlin_version"
|
||||
id "org.jetbrains.kotlin.plugin.noarg" version "${'$'}kotlin_version"
|
||||
id "org.jetbrains.kotlin.plugin.lombok" version "${'$'}kotlin_version"
|
||||
id "org.jetbrains.kotlin.plugin.power-assert" version "${'$'}kotlin_version"
|
||||
id "org.jetbrains.kotlin.plugin.sam.with.receiver" version "${'$'}kotlin_version"
|
||||
id "org.jetbrains.kotlin.plugin.serialization" version "${'$'}kotlin_version"
|
||||
id "org.jetbrains.kotlin.plugin.assignment" version "${'$'}kotlin_version"
|
||||
@@ -195,6 +196,7 @@ internal val DEFAULT_KOTLIN_SETTINGS_FILE =
|
||||
id("org.jetbrains.kotlin.plugin.jpa") version kotlin_version
|
||||
id("org.jetbrains.kotlin.plugin.noarg") version kotlin_version
|
||||
id("org.jetbrains.kotlin.plugin.lombok") version kotlin_version
|
||||
id("org.jetbrains.kotlin.plugin.power-assert") version kotlin_version
|
||||
id("org.jetbrains.kotlin.plugin.sam.with.receiver") version kotlin_version
|
||||
id("org.jetbrains.kotlin.plugin.serialization") version kotlin_version
|
||||
id("org.jetbrains.kotlin.plugin.assignment") version kotlin_version
|
||||
|
||||
+1
@@ -7,6 +7,7 @@ plugins {
|
||||
id 'org.jetbrains.kotlin.plugin.jpa'
|
||||
id 'org.jetbrains.kotlin.plugin.atomicfu'
|
||||
id 'org.jetbrains.kotlin.plugin.lombok'
|
||||
id 'org.jetbrains.kotlin.plugin.power-assert'
|
||||
id 'org.jetbrains.kotlin.plugin.sam.with.receiver'
|
||||
id 'org.jetbrains.kotlin.plugin.serialization'
|
||||
}
|
||||
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
plugins {
|
||||
kotlin("multiplatform")
|
||||
kotlin("plugin.power-assert")
|
||||
}
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
mavenLocal()
|
||||
}
|
||||
|
||||
kotlin {
|
||||
jvm()
|
||||
js()
|
||||
linuxX64()
|
||||
|
||||
sourceSets {
|
||||
val commonTest by getting {
|
||||
dependencies {
|
||||
implementation(kotlin("test-common"))
|
||||
implementation(kotlin("test-annotations-common"))
|
||||
}
|
||||
}
|
||||
val jvmTest by getting {
|
||||
dependencies {
|
||||
implementation(kotlin("test-junit"))
|
||||
}
|
||||
}
|
||||
val jsTest by getting {
|
||||
dependencies {
|
||||
implementation(kotlin("test-js"))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
powerAssert {
|
||||
functions = listOf(
|
||||
"kotlin.assert",
|
||||
"kotlin.test.assertTrue",
|
||||
"kotlin.require",
|
||||
"sample.AssertScope.assert",
|
||||
"sample.assert",
|
||||
"sample.dbg"
|
||||
)
|
||||
excludedSourceSets = listOf(
|
||||
"commonMain",
|
||||
"jvmMain",
|
||||
"jsMain",
|
||||
"linuxX64Main"
|
||||
)
|
||||
}
|
||||
+66
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright 2010-2024 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
// Copyright (C) 2020-2023 Brian Norman
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package sample
|
||||
|
||||
import kotlin.contracts.*
|
||||
|
||||
typealias LazyMessage = () -> Any
|
||||
|
||||
interface AssertScope {
|
||||
fun assert(assertion: Boolean, lazyMessage: LazyMessage? = null)
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalContracts::class)
|
||||
fun assert(assertion: Boolean, lazyMessage: LazyMessage? = null) {
|
||||
contract { returns() implies assertion }
|
||||
if (!assertion) {
|
||||
throw AssertionError(lazyMessage?.invoke()?.toString())
|
||||
}
|
||||
}
|
||||
|
||||
private class SoftAssertScope : AssertScope {
|
||||
private val assertions = mutableListOf<Throwable>()
|
||||
|
||||
override fun assert(assertion: Boolean, lazyMessage: LazyMessage?) {
|
||||
if (!assertion) {
|
||||
assertions.add(AssertionError(lazyMessage?.invoke()?.toString()))
|
||||
}
|
||||
}
|
||||
|
||||
fun close(exception: Throwable? = null) {
|
||||
if (assertions.isNotEmpty()) {
|
||||
val base = exception ?: AssertionError("Multiple failed assertions")
|
||||
for (assertion in assertions) {
|
||||
base.addSuppressed(assertion)
|
||||
}
|
||||
throw base
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalContracts::class)
|
||||
fun <R> assertSoftly(block: AssertScope.() -> R): R {
|
||||
contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) }
|
||||
|
||||
val scope = SoftAssertScope()
|
||||
val result = runCatching { scope.block() }
|
||||
scope.close(result.exceptionOrNull())
|
||||
return result.getOrThrow()
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright 2010-2024 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
// Copyright (C) 2021-2023 Brian Norman
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package sample
|
||||
|
||||
val debugLog = StringBuilder()
|
||||
|
||||
fun <T> dbg(value: T): T = value
|
||||
|
||||
fun <T> dbg(value: T, msg: String): T {
|
||||
debugLog.appendLine(msg)
|
||||
return value
|
||||
}
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright 2010-2024 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
// Copyright (C) 2020-2023 Brian Norman
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package sample;
|
||||
|
||||
data class Person(
|
||||
val firstName: String,
|
||||
val lastName: String,
|
||||
) {
|
||||
init {
|
||||
require(firstName.isNotBlank())
|
||||
require(lastName.isNotBlank())
|
||||
}
|
||||
|
||||
companion object {
|
||||
val UNKNOWN = listOf(Person("John", "Doe"), Person("Jane", "Doe"))
|
||||
override fun toString() = "Person.Companion"
|
||||
}
|
||||
}
|
||||
+165
@@ -0,0 +1,165 @@
|
||||
/*
|
||||
* Copyright 2010-2024 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
// Copyright (C) 2020-2023 Brian Norman
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package sample
|
||||
|
||||
import kotlin.test.AfterTest
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertFailsWith
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
class PowerAssertTest {
|
||||
|
||||
@AfterTest
|
||||
fun cleanup() {
|
||||
debugLog.clear()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun assertTrue() {
|
||||
val error = assertFailsWith<AssertionError> { assertTrue(Person.UNKNOWN.size == 1) }
|
||||
assertEquals(
|
||||
actual = error.message,
|
||||
expected = """
|
||||
Assertion failed
|
||||
assertTrue(Person.UNKNOWN.size == 1)
|
||||
| | | |
|
||||
| | | false
|
||||
| | 2
|
||||
| [Person(firstName=John, lastName=Doe), Person(firstName=Jane, lastName=Doe)]
|
||||
Person.Companion
|
||||
""".trimIndent()
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun require() {
|
||||
val error = assertFailsWith<IllegalArgumentException> { require(Person.UNKNOWN.size == 1) }
|
||||
assertEquals(
|
||||
actual = error.message,
|
||||
expected = """
|
||||
Assertion failed
|
||||
require(Person.UNKNOWN.size == 1)
|
||||
| | | |
|
||||
| | | false
|
||||
| | 2
|
||||
| [Person(firstName=John, lastName=Doe), Person(firstName=Jane, lastName=Doe)]
|
||||
Person.Companion
|
||||
""".trimIndent()
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun excludedRequire() {
|
||||
val error = assertFailsWith<IllegalArgumentException> { Person("", "") }
|
||||
assertEquals(
|
||||
actual = error.message,
|
||||
expected = "Failed requirement."
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun softAssert() {
|
||||
val unknown: List<Person>? = Person.UNKNOWN
|
||||
assert(unknown != null)
|
||||
assert(unknown.size == 2)
|
||||
|
||||
val error = assertFailsWith<AssertionError> {
|
||||
val jane: Person
|
||||
val john: Person
|
||||
assertSoftly {
|
||||
jane = unknown[0]
|
||||
assert(jane.firstName == "Jane")
|
||||
assert(jane.lastName == "Doe") { "bad jane last name" }
|
||||
|
||||
john = unknown[1]
|
||||
assert(john.lastName == "Doe" && john.firstName == "John") { "bad john" }
|
||||
}
|
||||
}
|
||||
assertEquals(
|
||||
actual = error.message,
|
||||
expected = """
|
||||
Multiple failed assertions
|
||||
""".trimIndent(),
|
||||
)
|
||||
assertEquals(
|
||||
actual = error.suppressedExceptions.size,
|
||||
expected = 2,
|
||||
)
|
||||
assertEquals(
|
||||
actual = error.suppressedExceptions[0].message,
|
||||
expected = """
|
||||
Assertion failed
|
||||
assert(jane.firstName == "Jane")
|
||||
| | |
|
||||
| | false
|
||||
| John
|
||||
Person(firstName=John, lastName=Doe)
|
||||
""".trimIndent(),
|
||||
)
|
||||
assertEquals(
|
||||
actual = error.suppressedExceptions[1].message,
|
||||
expected = """
|
||||
bad john
|
||||
assert(john.lastName == "Doe" && john.firstName == "John") { "bad john" }
|
||||
| | | | | |
|
||||
| | | | | false
|
||||
| | | | Jane
|
||||
| | | Person(firstName=Jane, lastName=Doe)
|
||||
| | true
|
||||
| Doe
|
||||
Person(firstName=Jane, lastName=Doe)
|
||||
""".trimIndent(),
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun dbgTest() {
|
||||
val name = "Jane"
|
||||
val greeting = dbg("Hello, $name")
|
||||
assert(greeting == "Hello, Jane")
|
||||
assertEquals(
|
||||
actual = debugLog.toString().trim(),
|
||||
expected = """
|
||||
dbg("Hello, ${"$"}name")
|
||||
| |
|
||||
| Jane
|
||||
Hello, Jane
|
||||
""".trimIndent()
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun dbgMessageTest() {
|
||||
val name = "Jane"
|
||||
val greeting = dbg("Hello, $name", "Greeting:")
|
||||
assert(greeting == "Hello, Jane")
|
||||
assertEquals(
|
||||
actual = debugLog.toString().trim(),
|
||||
expected = """
|
||||
Greeting:
|
||||
dbg("Hello, ${"$"}name", "Greeting:")
|
||||
| |
|
||||
| Jane
|
||||
Hello, Jane
|
||||
""".trimIndent()
|
||||
)
|
||||
}
|
||||
}
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright 2010-2024 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
// Copyright (C) 2020-2023 Brian Norman
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package sample
|
||||
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertFailsWith
|
||||
|
||||
class JsPowerAssertTest {
|
||||
@Test
|
||||
fun assert() {
|
||||
val error = assertFailsWith<IllegalArgumentException> {
|
||||
require(Person.UNKNOWN.size == 1) { "unknown persons: ${Person.UNKNOWN}" }
|
||||
}
|
||||
assertEquals(
|
||||
actual = error.message,
|
||||
expected = """
|
||||
unknown persons: [Person(firstName=John, lastName=Doe), Person(firstName=Jane, lastName=Doe)]
|
||||
require(Person.UNKNOWN.size == 1) { "unknown persons: ${"$"}{Person.UNKNOWN}" }
|
||||
| | | |
|
||||
| | | false
|
||||
| | 2
|
||||
| [Person(firstName=John, lastName=Doe), Person(firstName=Jane, lastName=Doe)]
|
||||
Person.Companion
|
||||
""".trimIndent(),
|
||||
)
|
||||
}
|
||||
}
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright 2010-2024 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
// Copyright (C) 2020-2023 Brian Norman
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package sample
|
||||
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertFailsWith
|
||||
|
||||
class JvmPowerAssertTest {
|
||||
@Test
|
||||
fun assert() {
|
||||
val error = assertFailsWith<AssertionError> {
|
||||
assert(Person.UNKNOWN.size == 1) { "unknown persons: ${Person.UNKNOWN}" }
|
||||
}
|
||||
assertEquals(
|
||||
actual = error.message,
|
||||
expected = """
|
||||
unknown persons: [Person(firstName=John, lastName=Doe), Person(firstName=Jane, lastName=Doe)]
|
||||
assert(Person.UNKNOWN.size == 1) { "unknown persons: ${"$"}{Person.UNKNOWN}" }
|
||||
| | | |
|
||||
| | | false
|
||||
| | 2
|
||||
| [Person(firstName=John, lastName=Doe), Person(firstName=Jane, lastName=Doe)]
|
||||
Person.Companion
|
||||
""".trimIndent(),
|
||||
)
|
||||
}
|
||||
}
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright 2010-2024 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
// Copyright (C) 2020-2023 Brian Norman
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package sample
|
||||
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertFailsWith
|
||||
|
||||
class NativePowerAssertTest {
|
||||
@Test
|
||||
fun assert() {
|
||||
val error = assertFailsWith<AssertionError> {
|
||||
assert(Person.UNKNOWN.size == 1) { "unknown persons: ${Person.UNKNOWN}" }
|
||||
}
|
||||
assertEquals(
|
||||
actual = error.message,
|
||||
expected = """
|
||||
unknown persons: [Person(firstName=John, lastName=Doe), Person(firstName=Jane, lastName=Doe)]
|
||||
assert(Person.UNKNOWN.size == 1) { "unknown persons: ${"$"}{Person.UNKNOWN}" }
|
||||
| | | |
|
||||
| | | false
|
||||
| | 2
|
||||
| [Person(firstName=John, lastName=Doe), Person(firstName=Jane, lastName=Doe)]
|
||||
Person.Companion
|
||||
""".trimIndent(),
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -246,6 +246,10 @@ any distributions of the tools or libraries:
|
||||
and Eclipse Distribution License - v1.0 ([license/third_party/testdata/eclipse_distribution_license.txt][eclipse-distribution])
|
||||
- Origin: javax.persistence, Copyright (c) 2008, 2017 Sun Microsystems, Oracle Corporation.
|
||||
|
||||
- Path: libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/powerAssertSimple
|
||||
- License: Apache 2 ([license/third_party/power_assert_license.txt][power-assert])
|
||||
- Origin: Copyright (C) 2020-2023 Brian Norman
|
||||
|
||||
- Path: libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/nodejs/Platform.kt
|
||||
- License: Apache License 2.0 ([license/third_party/gradle-node-plugin_LICENSE.txt](third_party/gradle-node-plugin_LICENSE.txt))
|
||||
- Origin: Copyright (c) 2013 node-gradle/gradle-node-plugin
|
||||
|
||||
Reference in New Issue
Block a user