lydavid / MusicSearch

An Android app for browsing songs, artists, and anything related to them
Apache License 2.0
18 stars 0 forks source link

for testing, change back #902

Closed github-actions[bot] closed 2 months ago

github-actions[bot] commented 2 months ago

https://github.com/lydavid/MusicSearch/blob/7b3d6899f2d507d01f8c9cd08df7fa87e506547c/build.gradle.kts#L272


// Original from https://github.com/JakeWharton/SdkSearch/blob/master/gradle/projectDependencyGraph.gradle
// kts version from https://github.com/leinardi/Forlago/blob/e47f2d8781b8a05e074bf2b761e1693b14b7a06c/build-conventions/src/main/kotlin/forlago.dependency-graph-conventions.gradle.kts
allprojects {
    tasks.register("projectDependencyGraph") {
        group = projectGroup

        inputs.files(
            fileTree(rootDir) {
                include("**/build.gradle.kts")
            },
        )

        val graphSvgFile = "$projectDir/assets/module_dependency_graph.svg"
        outputs.file(graphSvgFile)
        val readmeFile = file("$projectDir/README.md")
        outputs.file(readmeFile)

        doLast {
            val dot = project.layout.buildDirectory.file("reports/dependency-graph/project.dot").get().asFile
            dot.parentFile.mkdirs()
            dot.delete()

            dot.writeText("digraph {\n")
            dot.appendText("  graph [label=\"Dependencies\\n \",labelloc=t,fontsize=30,ranksep=1.4];\n")
            dot.appendText("  node [style=filled, fillcolor=\"#bbbbbb\"];\n")
            dot.appendText("  rankdir=TB;\n")
            dot.appendText("  splines=ortho;\n")

            val projects = LinkedHashSet<Project>()
            val multiplatformProjects = mutableListOf<Project>()
            val jsProjects = mutableListOf<Project>()
            val androidProjects = mutableListOf<Project>()
            val javaProjects = mutableListOf<Project>()

            // Find all projects in this repository and group them accordingly
            val queue = mutableListOf(rootProject)
            while (queue.isNotEmpty()) {
                val currentProject = queue.removeFirst()

                // A child project is not necessarily a dependency
                // eg. :feature:collections is child project of :shared
                queue.addAll(currentProject.childProjects.values)

                if (currentProject.plugins.hasPlugin("org.jetbrains.kotlin.multiplatform")) {
                    multiplatformProjects.add(currentProject)
                }
                if (currentProject.plugins.hasPlugin("org.jetbrains.kotlin.js")) {
                    jsProjects.add(currentProject)
                }
                if (currentProject.plugins.hasPlugin("com.android.library") ||
                    currentProject.plugins.hasPlugin("com.android.application")
                ) {
                    androidProjects.add(currentProject)
                }
                if (currentProject.plugins.hasPlugin("java-library") || currentProject.plugins.hasPlugin("java")) {
                    javaProjects.add(currentProject)
                }
            }

            val dependencies = LinkedHashMap<Pair<Project, Project>, List<String>>()

            // Find all dependencies of this project and their dependencies
            val newQueue = mutableListOf(project)
            while (newQueue.isNotEmpty()) {
                val currentProject = newQueue.removeFirst()

                currentProject.configurations.forEach outer@{ config ->
                    config.dependencies
                        .withType(ProjectDependency::class.java)
                        .map { it.dependencyProject }
                        .filter { currentProject != rootProject }
                        .filter { currentProject != it }
                        .forEach inner@{ dependency ->

                            projects.add(currentProject)
                            projects.add(dependency)
                            newQueue.add(dependency)

                            val traits = mutableListOf<String>()
                            if (currentProject.path.split(":").getOrNull(1)?.equals("ui") == true &&
                                dependency.path.contains("data")
                            ) {
                                traits.add("color=orange")
                            } else if (currentProject.path.split(":").getOrNull(1)?.equals("ui") == true &&
                                dependency.path.split(":").getOrNull(1)?.equals("ui") == true
                            ) {
                                traits.add("color=red")
                            } else if (config.name.lowercase().endsWith("implementation")) {
                                traits.add("style=dotted")
                            }
                            if (config.name.lowercase().contains("test")) {
                                traits.add("color=\"#ff9ab1\"")
                            }
                            dependencies[currentProject to dependency] = traits
                        }
                }
            }

            // Don't create an svg for projects with no dependencies
            if (dependencies.isEmpty()) {
                return@doLast
            }

            projects.sortedBy { it.path }

//            println("\nAll projects")
//            projects.forEach { project ->
//                println(project)
//            }
//            println("\nDependencies")
//            for ((key, value) in dependencies) {
//                println("$key $value")
//            }

            dot.appendText("\n  # Projects\n\n")
            for (currentProject in projects) {
                val traits = mutableListOf<String>()

                if (currentProject == project) {
                    traits.add("shape=box")
                    traits.add("width=5")
                }

                if (multiplatformProjects.contains(currentProject)) {
                    traits.add("fillcolor=\"#b59aff\"")
                } else if (jsProjects.contains(currentProject)) {
                    traits.add("fillcolor=\"#ffe89a\"")
                } else if (androidProjects.contains(currentProject)) {
                    traits.add("fillcolor=\"#9affb5\"")
                } else if (javaProjects.contains(currentProject)) {
                    traits.add("fillcolor=\"#ffb59a\"")
                } else {
                    traits.add("fillcolor=\"#eeeeee\"")
                }

                dot.appendText("  \"${currentProject.path}\" [${traits.joinToString(", ")}];\n")
            }

            dot.appendText("\n  # Dependencies\n\n")
            dependencies.forEach { (key, traits) ->
                dot.appendText("  \"${key.first.path}\" -> \"${key.second.path}\"")
                if (traits.isNotEmpty()) {
                    dot.appendText(" [${traits.joinToString(", ")}]")
                }
                dot.appendText("\n")
            }

            dot.appendText("}\n")

            val p = Runtime.getRuntime().exec(
                arrayOf(
                    "/opt/homebrew/bin/dot", // TODO: for testing, change back
                    "-Tsvg",
                    "project.dot",
                    "-o",
                    graphSvgFile,
                ),
                emptyArray(),
                dot.parentFile,
            )
            p.waitFor()
            require(p.exitValue() == 0) { p.errorStream.bufferedReader().use(BufferedReader::readText) }

            println("Project module dependency graph created at ${dot.absolutePath}.svg")

            if (!readmeFile.exists()) {
                readmeFile.writeText(
                    """
                    # ${project.path}

                    Do not edit this file.
                    It was automatically generated by the `projectDependencyGraph` task.

                    ## Dependencies
                    ![](assets/module_dependency_graph.svg)

                    """.trimIndent(),
                )
            }
        }
    }
}
// endregion
github-actions[bot] commented 2 months ago

Closed in fbe42ebca6ad6b3b0ff3f43cb2bbed8410988798