diff --git a/build.gradle b/build.gradle index 6c1e6ae..5fbb981 100644 --- a/build.gradle +++ b/build.gradle @@ -19,6 +19,7 @@ repositories { dependencies { implementation 'org.jetbrains.kotlin:kotlin-stdlib' + implementation "org.jetbrains.kotlin:kotlin-reflect:$kotlinVersion" implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.7' implementation "com.xenomachina:kotlin-argparser:$kotlin_argparser_version" implementation "org.jetbrains.exposed:exposed-core:$kotlin_exposed_version" @@ -26,5 +27,7 @@ dependencies { implementation "org.jetbrains.exposed:exposed-jdbc:$kotlin_exposed_version" implementation "org.xerial:sqlite-jdbc:3.30.1" implementation 'com.google.code.gson:gson:2.8.6' + implementation 'org.python:jython-standalone:2.7.2' + implementation 'org.pygments:pygments:2.5.2' testImplementation 'junit:junit:4.12' } diff --git a/gradle.properties b/gradle.properties index fe5444e..c5cb12d 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ -kotlinVersion=1.3.71 +kotlinVersion=1.4.0 kotlin_argparser_version=2.0.7 kotlin_exposed_version=0.25.1 \ No newline at end of file diff --git a/src/main/kotlin/me/msoucy/gbat/Main.kt b/src/main/kotlin/me/msoucy/gbat/Main.kt index 29ca314..094cc17 100644 --- a/src/main/kotlin/me/msoucy/gbat/Main.kt +++ b/src/main/kotlin/me/msoucy/gbat/Main.kt @@ -115,9 +115,7 @@ fun main(args: Array) = mainBody { } return hasInterest } - - fun GitRepo.interestingNames() = ls().split("\n").filter { it.isInteresting() } - val fnames = repo.interestingNames() + val fnames = repo.ls().split("\n").filter { it.isInteresting() } if (fnames.isEmpty()) { System.err.println("No interesting files found, exiting.") diff --git a/src/main/kotlin/me/msoucy/gbat/Renderer.kt b/src/main/kotlin/me/msoucy/gbat/Renderer.kt index 62ecb3c..05b934d 100644 --- a/src/main/kotlin/me/msoucy/gbat/Renderer.kt +++ b/src/main/kotlin/me/msoucy/gbat/Renderer.kt @@ -1,40 +1,36 @@ package me.msoucy.gbat -import java.io.File - -import me.msoucy.gbat.models.ProjectTreeNode -import me.msoucy.gbat.models.ProjectTreeResult -import me.msoucy.gbat.models.Statistics -import me.msoucy.gbat.models.SummaryModel - import com.google.gson.GsonBuilder +import java.io.File +import me.msoucy.gbat.models.SummaryModel import org.jetbrains.exposed.sql.* import org.jetbrains.exposed.sql.transactions.transaction +import org.python.util.PythonInterpreter val NUM_RISKIEST_AUTHORS = 10 val NUM_RISKIEST_FILES = 10 class SummaryRenderer( - val summaryModel : SummaryModel, - val outputDir : File + val summaryModel: SummaryModel, + val outputDir: File ) { private val filesDir = File(outputDir, "files") private val gson = GsonBuilder().setPrettyPrinting().create() - fun renderAll(projectRoot : File) { + fun renderAll(projectRoot: File) { createFilesDir() renderSummaryJson(projectRoot) renderFileJson(projectRoot) - // renderSrc(projectRoot) + renderSrc(projectRoot) } - private fun renderSummaryJson(projectRoot : File) { + private fun renderSummaryJson(projectRoot: File) { val summary = summaryModel.projectSummary(projectRoot.absolutePath) val json = gson.toJson(summary) File(filesDir, "summary.json").writeText(json) } - private fun renderFileJson(projectRoot : File) { + private fun renderFileJson(projectRoot: File) { summaryModel.projectFiles(projectRoot.absolutePath).forEach { val json = gson.toJson(summaryModel.fileSummary(it.fileId)) File(filesDir, "${it.fileId}.json").writeText(json) @@ -42,15 +38,41 @@ class SummaryRenderer( } private fun createFilesDir() = filesDir.mkdirs() + + private fun renderSrc(projectRoot: File) { + val interpreter = PythonInterpreter() + val cssFile = File(filesDir, "pygments.css") + interpreter.exec(""" +from pygments.formatters import HtmlFormatter +formatter = HtmlFormatter(linenos=True, lineanchors='gbab') +formatCss = formatter.get_style_defs() +""") + cssFile.writeText(interpreter.get("formatCss", String::class.java)) + + summaryModel.projectFiles(projectRoot.absolutePath).forEach { + val resultFile = File(filesDir, "${it.fileId}.html") + val lines = summaryModel.fileLines(it.fileId) + val body = lines.joinToString("\n") + interpreter["fname"] = it.fname.toString() + interpreter["body"] = body + interpreter.exec(""" +from pygments import highlight +from pygments.lexers import guess_lexer_for_filename +lexer = guess_lexer_for_filename(fname, body) +html = highlight(body, lexer, formatter) +""") + resultFile.writeText("""""" + interpreter.get("html", String::class.java)) + } + } } fun renderSummary( - projectRoot : File, - summaryModel : SummaryModel, - outputDir : File + projectRoot: File, + summaryModel: SummaryModel, + outputDir: File ) { transaction(summaryModel.db) { val renderer = SummaryRenderer(summaryModel, outputDir) renderer.renderAll(projectRoot) } -} \ No newline at end of file +} diff --git a/src/main/kotlin/me/msoucy/gbat/Repo.kt b/src/main/kotlin/me/msoucy/gbat/Repo.kt index 96b5f25..2683b3b 100644 --- a/src/main/kotlin/me/msoucy/gbat/Repo.kt +++ b/src/main/kotlin/me/msoucy/gbat/Repo.kt @@ -14,6 +14,7 @@ class GitRepo(val projectRoot: File, val git_exe: String) { "--name-only", "-r", "HEAD", + "--", projectRoot.absolutePath ) val (out, _) = cmd.runCommand(projectRoot) @@ -40,6 +41,7 @@ class GitRepo(val projectRoot: File, val git_exe: String) { "--follow", // Follow history through renames "--patience", // Use the patience diff algorithm "-p", // Show patches + "--", fname.absolutePath ) val (out, err) = cmd.runCommand(projectRoot)