(\"clean\").configure {\n" +
477 | " delete(rootProject.buildDir)\n }"
478 |
479 | return this.replace(cleanExp, registerClean)
480 | }
481 |
482 |
483 | // androidExtensions { experimental = true }
484 | // becomes
485 | // androidExtensions { isExperimental = true }
486 | fun String.convertInternalBlocks(): String {
487 | return this.addIsToStr("androidExtensions", "experimental")
488 | .addIsToStr("dataBinding", "enabled")
489 | .addIsToStr("lintOptions", "abortOnError")
490 | .addIsToStr("buildTypes", "debuggable")
491 | .addIsToStr("buildTypes", "minifyEnabled")
492 | .addIsToStr("buildTypes", "shrinkResources")
493 | .addIsToStr("", "transitive")
494 | }
495 |
496 | fun String.addIsToStr(blockTitle: String, transform: String): String {
497 |
498 | val extensionsExp = "$blockTitle\\s*\\{[\\s\\S]*\\}".toRegex()
499 |
500 | if (!extensionsExp.containsMatchIn(this)) return this
501 |
502 | val typesExp = "$transform.*".toRegex()
503 |
504 | return this.replace(typesExp) {
505 |
506 | val split = it.value.split(" ")
507 |
508 | // if there is more than one whitespace, the last().toIntOrNull() will find.
509 | if (split.lastOrNull { it.isNotBlank() } != null) {
510 | "is${split[0].capitalize()} = ${split.last()}"
511 | } else {
512 | it.value
513 | }
514 | }
515 | }
516 |
517 |
518 | // include ":app", ":diffutils"
519 | // becomes
520 | // include(":app", ":diffutils")
521 | fun String.convertInclude(): String {
522 |
523 | val expressionBase = "\\s*((\".*\"\\s*,)\\s*)*(\".*\")".toRegex()
524 | val includeExp = "include$expressionBase".toRegex()
525 |
526 | return this.replace(includeExp) { includeBlock ->
527 | if (includeBlock.value.contains("include\"")) return@replace includeBlock.value // exclude: "include" to
528 |
529 | // avoid cases where some lines at the start/end are blank
530 | val multiLine = includeBlock.value.split('\n').count { it.isNotBlank() } > 1
531 |
532 | val isolated = expressionBase.find(includeBlock.value)?.value ?: ""
533 | if (multiLine) "include(\n${isolated.trim()}\n)" else "include(${isolated.trim()})"
534 | // Possible visual improvement: when using multiline, the first line should have the same
535 | // margin/spacement as the others.
536 | }
537 | }
538 |
539 |
540 | // configurations.classpath.exclude group: 'com.android.tools.external.lombok'
541 | // becomes
542 | // configurations.classpath {
543 | // exclude(group = "com.android.tools.external.lombok")
544 | // }
545 | fun String.convertExcludeClasspath(): String {
546 |
547 | val fullLineExp = ".*configurations\\.classpath\\.exclude.*group:.*".toRegex()
548 |
549 | // this will extract "com.android.tools.external.lombok" from the string.
550 | val innerExp = "\".*\"".toRegex()
551 |
552 | return this.replace(fullLineExp) { isolatedLine ->
553 | val isolatedStr = innerExp.find(isolatedLine.value)?.value ?: ""
554 | "configurations.classpath {\n" +
555 | " exclude(group = $isolatedStr)\n" +
556 | "}"
557 | }
558 | }
559 |
560 | // exclude module: 'module-id'
561 | // becomes
562 | // exclude(module = "module-id")
563 | fun String.convertExcludeModules(): String {
564 | val fullLineExp = """exclude module: (\S+)""".toRegex()
565 |
566 | return this.replace(fullLineExp) {
567 | val (moduleId) = it.destructured
568 | "exclude(module = $moduleId)"
569 | }
570 | }
571 |
572 | // exclude group: 'group-id'
573 | // becomes
574 | // exclude(group = "group-id")
575 | fun String.convertExcludeGroups(): String {
576 | val fullLineExp = """exclude group: (\S+)""".toRegex()
577 |
578 | return this.replace(fullLineExp) {
579 | val (groupId) = it.destructured
580 | "exclude(group = $groupId)"
581 | }
582 | }
583 |
584 | // classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
585 | // becomes
586 | // classpath(kotlin("gradle-plugin", version = "$kotlin_version"))
587 | //
588 | // implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
589 | // becomes
590 | // implementation(kotlin("stdlib", KotlinCompilerVersion.VERSION))
591 | fun String.convertJetBrainsKotlin(): String {
592 |
593 | // if string is implementation("..."), this will extract only the ...
594 | val fullLineExp = "\"org.jetbrains.kotlin:kotlin-.*(?=\\))".toRegex()
595 |
596 | val removeExp = "(?!org.jetbrains.kotlin:kotlin)-.*".toRegex()
597 |
598 | var shouldImportKotlinCompiler = false
599 |
600 | val newText = this.replace(fullLineExp) { isolatedLine ->
601 |
602 | // drop first "-" and remove last "
603 | val substring = (removeExp.find(isolatedLine.value)?.value ?: "").drop(1).replace("\"", "")
604 |
605 | val splittedSubstring = substring.split(":")
606 |
607 | if ("stdlib" in substring) {
608 | shouldImportKotlinCompiler = true
609 | "kotlin(\"stdlib\", KotlinCompilerVersion.VERSION)"
610 | } else if (splittedSubstring.size == 2) {
611 | "kotlin(\"${splittedSubstring[0]}\", version = \"${splittedSubstring[1]}\")"
612 | } else {
613 | "kotlin(\"${splittedSubstring[0]}\")"
614 | }
615 | }
616 |
617 | return if (shouldImportKotlinCompiler) {
618 | "import org.jetbrains.kotlin.config.KotlinCompilerVersion\n\n" + newText
619 | } else {
620 | newText
621 | }
622 | }
623 |
624 |
625 | // apply(plugin = "com.trello.victor")
626 | // becomes within plugin{}
627 | // id("com.trello.victor")
628 | fun String.convertPluginsIntoOneBlock(): String {
629 |
630 | // group plugin expressions. There can't be any space or tabs on the start of the line, else the regex will fail.
631 | // ok example:
632 | // apply(...)
633 | // apply(...)
634 | //
635 | // not ok example:
636 | // apply(...)
637 | // apply(...)
638 | val fullLineExp = "(apply\\(plugin\\s*=\\s*\".*\"\\)[\\s\\S]){2,}".toRegex()
639 |
640 | val isolatedId = "\".*\"(?=\\))".toRegex()
641 |
642 | return this.replace(fullLineExp) { isolatedLine ->
643 | // this will fold the ids into a single string
644 | val plugins = isolatedId.findAll(isolatedLine.value)?.fold("") { acc, matchResult ->
645 | acc + " id(${matchResult.value})\n"
646 | }
647 | "plugins {\n$plugins}\n"
648 | }
649 | }
650 |
651 | // testImplementation(group: "junit", name: "junit", version: "4.12")
652 | // becomes
653 | // testImplementation(group = "junit", name = "junit", version = "4.12")
654 | fun String.replaceColonWithEquals(): String {
655 |
656 | // this get "group:"
657 | val expression = "\\w*:\\s*\".*?\"".toRegex()
658 |
659 | return this.replace(expression) {
660 | it.value.replace(":", " =")
661 | }
662 | }
663 |
664 | // coreLibraryDesugaringEnabled = true
665 | // becomes
666 | // isCoreLibraryDesugaringEnabled = true
667 | fun String.replaceCoreLibraryDesugaringEnabled(): String = this.replace(
668 | oldValue = "coreLibraryDesugaringEnabled", newValue = "isCoreLibraryDesugaringEnabled"
669 | )
670 | }
671 |
--------------------------------------------------------------------------------
/src/jsMain/kotlin/Sample.kt:
--------------------------------------------------------------------------------
1 | @OptIn(ExperimentalJsExport::class)
2 | @JsExport
3 | object Sample {
4 | //language=Groovy
5 | const val GROOVY = """plugins {
6 | id 'com.android.application'
7 | }
8 |
9 | android {
10 | namespace 'com.example.myapp'
11 | compileSdkVersion 28
12 | defaultConfig {
13 | applicationId 'com.example.myapp'
14 | minSdkVersion 15
15 | targetSdkVersion 28
16 | versionCode 1
17 | versionName "1.0"
18 | }
19 |
20 | buildTypes {
21 | release {
22 | minifyEnabled true
23 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
24 | }
25 | }
26 |
27 | flavorDimensions "tier"
28 | productFlavors {
29 | free {
30 | dimension "tier"
31 | applicationId 'com.example.myapp.free'
32 | }
33 |
34 | paid {
35 | dimension "tier"
36 | applicationId 'com.example.myapp.paid'
37 | }
38 | }
39 | }
40 |
41 | dependencies {
42 | implementation project(":lib")
43 | implementation 'com.android.support:appcompat-v7:28.0.0'
44 | implementation fileTree(dir: 'libs', include: ['*.jar'])
45 | }
46 |
47 | """
48 | }
49 |
--------------------------------------------------------------------------------
/src/jsMain/resources/assets/css/styles.css:
--------------------------------------------------------------------------------
1 | p {
2 | padding-left: 16px;
3 | padding-right: 16px;
4 | }
5 |
6 |
--------------------------------------------------------------------------------
/src/jsMain/resources/assets/img/Screenshot 2021-02-25 214819.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cvb941/gradlekotlinize/f77b4abb51a7776d6f8b902dbd4531b6c43c867e/src/jsMain/resources/assets/img/Screenshot 2021-02-25 214819.png
--------------------------------------------------------------------------------
/src/jsMain/resources/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Convert Groovy to Kotlin Online | Gradle Kotlinize
8 |
9 |
10 |
11 |
13 |
14 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
42 | Gradle Kotlinize - Groovy
43 | to Kotlin converter online
44 |
45 |
46 |
47 | Paste your build.gradle into the left box. The contents will then be converted from Groovy to the new
48 | Kotlin-based Gradle build file format in the right box. Use the output in a file named build.gradle.kts in your project.
49 |
50 |
51 |
Groovy input - build.gradle
52 |
53 |
54 |
Kotlin output - build.gradle.kts
55 |
56 |
57 |
58 |
59 | Gradle Kotlinize is an online tool to convert Gradle Groovy to Kotlin kts
60 | format (convert build.gradle to build.gradle.kts)
61 |
62 |
66 |
67 |
104 |
105 |
129 |
130 |
131 |
132 |
--------------------------------------------------------------------------------
/src/jsMain/resources/sitemap.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | https://gradle-kotlinize.web.app/index.html
5 |
6 |
--------------------------------------------------------------------------------
/src/jsTest/kotlin/TestClient.kt:
--------------------------------------------------------------------------------
1 | import kotlinx.browser.document
2 | import kotlin.test.Test
3 | import kotlin.test.assertEquals
4 |
5 | class TestClient {
6 | }
7 |
--------------------------------------------------------------------------------