gins.gradle-api.6.9.1.source-code.Main.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of gradle-api Show documentation
Show all versions of gradle-api Show documentation
Gradle 8.10 API redistribution.
/*
* Copyright 2019 the original author or authors.
*
* 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.
*/
import data.Trie
import elmish.elementById
import elmish.mountComponentAt
import elmish.tree.Tree
import elmish.tree.TreeView
import kotlin.js.JSON.stringify
fun main() {
mountComponentAt(
elementById("report"),
ConfigurationCacheReportPage,
reportPageModelFromJsModel(configurationCacheProblems())
)
}
/**
* External model defined in `configuration-cache-report-data.js`, a file generated by `ConfigurationCacheReport`.
*/
private
external val configurationCacheProblems: () -> JsModel
private
external interface JsModel {
val cacheAction: String
val documentationLink: String
val problems: Array
}
private
external interface JsProblem {
val trace: Array
val message: Array
val error: String?
val documentationLink: String?
}
private
external interface JsTrace {
val kind: String
}
private
external interface JsTraceTask : JsTrace {
val path: String
val type: String
}
private
external interface JsTraceBean : JsTrace {
val type: String
}
private
external interface JsTraceField : JsTrace {
val name: String
val declaringType: String
}
private
external interface JsTraceProperty : JsTrace {
val name: String
val task: String
}
private
external interface JSBuildLogic : JsTrace {
val location: String
}
private
external interface JSBuildLogicClass : JsTrace {
val type: String
}
private
external interface JsMessageFragment {
val text: String?
val name: String?
}
private
data class ImportedProblem(
val problem: JsProblem,
val message: PrettyText,
val trace: List
)
private
fun reportPageModelFromJsModel(jsModel: JsModel): ConfigurationCacheReportPage.Model {
val problems = jsModel.problems.map { jsProblem ->
ImportedProblem(
jsProblem,
jsProblem.message.let(::toPrettyText),
jsProblem.trace.map(::toProblemNode)
)
}
return ConfigurationCacheReportPage.Model(
cacheAction = jsModel.cacheAction,
documentationLink = jsModel.documentationLink,
totalProblems = jsModel.problems.size,
messageTree = treeModelFor(
ProblemNode.Label("Problems grouped by message"),
problemNodesByMessage(problems)
),
locationTree = treeModelFor(
ProblemNode.Label("Problems grouped by location"),
problemNodesByLocation(problems)
)
)
}
private
fun problemNodesByMessage(problems: List): Sequence> =
problems.asSequence().map { problem ->
mutableListOf().apply {
add(
errorOrWarningNodeFor(
problem.problem,
messageNodeFor(problem),
docLinkFor(problem.problem)
)
)
addAll(problem.trace)
exceptionNodeFor(problem.problem)?.let {
add(it)
}
}
}
private
fun problemNodesByLocation(problems: List): Sequence> =
problems.asSequence().map { problem ->
mutableListOf().apply {
addAll(problem.trace.asReversed())
add(
errorOrWarningNodeFor(
problem.problem,
messageNodeFor(problem),
docLinkFor(problem.problem)
)
)
exceptionNodeFor(problem.problem)?.let {
add(it)
}
}
}
private
fun toPrettyText(message: Array) = PrettyText(
message.map {
it.text?.let(PrettyText.Fragment::Text)
?: it.name?.let(PrettyText.Fragment::Reference)
?: PrettyText.Fragment.Text("Unrecognised message fragment: ${stringify(it)}")
}
)
private
fun toProblemNode(trace: JsTrace): ProblemNode = when (trace.kind) {
"Task" -> trace.unsafeCast().run {
ProblemNode.Task(path, type)
}
"Bean" -> trace.unsafeCast().run {
ProblemNode.Bean(type)
}
"Field" -> trace.unsafeCast().run {
ProblemNode.Property("field", name, declaringType)
}
"InputProperty" -> trace.unsafeCast().run {
ProblemNode.Property("input property", name, task)
}
"OutputProperty" -> trace.unsafeCast().run {
ProblemNode.Property("output property", name, task)
}
"BuildLogic" -> trace.unsafeCast().run {
ProblemNode.BuildLogic(location)
}
"BuildLogicClass" -> trace.unsafeCast().run {
ProblemNode.BuildLogicClass(type)
}
else -> ProblemNode.Label("Gradle runtime")
}
private
fun errorOrWarningNodeFor(problem: JsProblem, label: ProblemNode, docLink: ProblemNode?): ProblemNode =
problem.error?.let {
ProblemNode.Error(label, docLink)
} ?: ProblemNode.Warning(label, docLink)
private
fun messageNodeFor(importedProblem: ImportedProblem) =
ProblemNode.Message(importedProblem.message)
private
fun exceptionNodeFor(it: JsProblem): ProblemNode? =
it.error?.let(ProblemNode::Exception)
private
fun docLinkFor(it: JsProblem): ProblemNode? =
it.documentationLink?.let { ProblemNode.Link(it, " ?") }
private
fun treeModelFor(
label: T,
sequence: Sequence>
): TreeView.Model = TreeView.Model(
treeFromTrie(
label,
Trie.from(sequence),
Tree.ViewState.Collapsed
)
)
private
fun treeFromTrie(label: T, trie: Trie, state: Tree.ViewState): Tree {
val subTreeState = if (trie.size == 1) Tree.ViewState.Expanded else Tree.ViewState.Collapsed
return Tree(
label,
subTreesFromTrie(trie, subTreeState),
// nodes with no children such as Exception nodes are considered `Collapsed` by default
if (trie.size == 0) Tree.ViewState.Collapsed else state
)
}
private
fun subTreesFromTrie(trie: Trie, state: Tree.ViewState): List> =
trie.entries.sortedBy { (label, _) -> label.toString() }.map { (label, subTrie) ->
treeFromTrie(
label,
subTrie,
state
)
}.toList()