mirror of
https://github.com/InsanusMokrassar/KotlinPublicationScriptsBuilder.git
synced 2025-09-03 06:59:17 +00:00
Compare commits
21 Commits
build-17e2
...
build-9a95
Author | SHA1 | Date | |
---|---|---|---|
9a95bddf08 | |||
c880d8e657 | |||
ac87a140cc | |||
0dbe3a866b | |||
7c50c58a90 | |||
ceff1eb1ef | |||
46d6d429bb | |||
dd9e71c9a2 | |||
6d2ffb8a6e | |||
25767eecb2 | |||
603da9a021 | |||
b43016bb24 | |||
4c4845803d | |||
4ec7d3847f | |||
2bbfe99ff4 | |||
881d268ea9 | |||
0c8eef971a | |||
7aa30ef46c | |||
aa1756724a | |||
741ee98e35 | |||
adae81b363 |
19
.github/workflows/build.yml
vendored
19
.github/workflows/build.yml
vendored
@@ -1,16 +1,17 @@
|
||||
name: Build
|
||||
|
||||
on: [push]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
name: Build
|
||||
|
||||
jobs:
|
||||
build-ubuntu:
|
||||
name: Commit release
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Set up JDK 11
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
- name: Setup JDK
|
||||
uses: actions/setup-java@v1
|
||||
with:
|
||||
java-version: 11
|
||||
- name: Build with Gradle
|
||||
run: ./gradlew build
|
||||
- name: Build
|
||||
run: ./gradlew build packageUberJarForCurrentOS
|
||||
|
15
.github/workflows/commit-release.yml
vendored
15
.github/workflows/commit-release.yml
vendored
@@ -1,4 +1,7 @@
|
||||
on: [push]
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
|
||||
name: Commit release
|
||||
|
||||
@@ -16,9 +19,13 @@ jobs:
|
||||
- name: Set version from gradle.properties
|
||||
run: echo "version=` cat gradle.properties | grep ^version= | grep -o [\\.0-9]* `" >> $GITHUB_ENV
|
||||
- name: Build
|
||||
run: ./gradlew packageUberJarForCurrentOS
|
||||
env:
|
||||
additional_version: ""
|
||||
run: ./gradlew build packageUberJarForCurrentOS
|
||||
- name: Publish Web
|
||||
uses: peaceiris/actions-gh-pages@v3
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
publish_dir: ./web/build/distributions
|
||||
publish_branch: site
|
||||
- name: Create Release
|
||||
id: create_release
|
||||
uses: actions/create-release@v1
|
||||
|
1
.gitignore
vendored
1
.gitignore
vendored
@@ -10,3 +10,4 @@ build/
|
||||
out/
|
||||
|
||||
local.properties
|
||||
kotlin-js-store/
|
||||
|
@@ -1,6 +1,5 @@
|
||||
buildscript {
|
||||
repositories {
|
||||
jcenter()
|
||||
google()
|
||||
mavenCentral()
|
||||
mavenLocal()
|
||||
@@ -8,7 +7,7 @@ buildscript {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:4.0.2'
|
||||
classpath 'com.android.tools.build:gradle:7.0.4'
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
classpath "org.jetbrains.kotlin:kotlin-serialization:$kotlin_version"
|
||||
classpath "com.getkeepsafe.dexcount:dexcount-gradle-plugin:$dexcount_version"
|
||||
@@ -19,10 +18,8 @@ buildscript {
|
||||
allprojects {
|
||||
repositories {
|
||||
mavenLocal()
|
||||
jcenter()
|
||||
mavenCentral()
|
||||
google()
|
||||
maven { url "https://kotlin.bintray.com/kotlinx" }
|
||||
maven { url "https://maven.pkg.jetbrains.space/public/p/compose/dev" }
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,27 @@
|
||||
package dev.inmo.kmppscriptbuilder.core.export
|
||||
|
||||
import dev.inmo.kmppscriptbuilder.core.models.GpgSigning
|
||||
|
||||
fun GpgSigning.generateMavenConfig() = when (this) {
|
||||
GpgSigning.Disabled -> ""
|
||||
GpgSigning.Optional ->
|
||||
"""
|
||||
if (project.hasProperty("signing.gnupg.keyName")) {
|
||||
apply plugin: 'signing'
|
||||
|
||||
signing {
|
||||
useGpgCmd()
|
||||
|
||||
sign publishing.publications
|
||||
}
|
||||
}"""
|
||||
GpgSigning.Enabled ->
|
||||
"""
|
||||
apply plugin: 'signing'
|
||||
|
||||
signing {
|
||||
useGpgCmd()
|
||||
|
||||
sign publishing.publications
|
||||
}"""
|
||||
}
|
@@ -0,0 +1,67 @@
|
||||
package dev.inmo.kmppscriptbuilder.core.export.js_only
|
||||
|
||||
import dev.inmo.kmppscriptbuilder.core.export.generateMavenConfig
|
||||
import dev.inmo.kmppscriptbuilder.core.models.*
|
||||
|
||||
fun MavenConfig.buildJsOnlyMavenConfig(licenses: List<License>): String = """
|
||||
apply plugin: 'maven-publish'
|
||||
|
||||
task javadocJar(type: Jar) {
|
||||
classifier = 'javadoc'
|
||||
}
|
||||
task sourcesJar(type: Jar) {
|
||||
kotlin.sourceSets.all {
|
||||
from(kotlin)
|
||||
}
|
||||
classifier = 'sources'
|
||||
}
|
||||
|
||||
publishing {
|
||||
publications {
|
||||
maven(MavenPublication) {
|
||||
kotlin.js().components.forEach {
|
||||
from(it)
|
||||
}
|
||||
|
||||
artifact javadocJar
|
||||
artifact sourcesJar
|
||||
|
||||
pom {
|
||||
resolveStrategy = Closure.DELEGATE_FIRST
|
||||
|
||||
description = "$description"
|
||||
name = "$name"
|
||||
url = "$url"
|
||||
|
||||
scm {
|
||||
developerConnection = "scm:git:[fetch=]${vcsUrl}[push=]${vcsUrl}"
|
||||
url = "$vcsUrl"
|
||||
}
|
||||
|
||||
developers {
|
||||
${developers.joinToString("\n") { """
|
||||
developer {
|
||||
id = "${it.id}"
|
||||
name = "${it.name}"
|
||||
email = "${it.eMail}"
|
||||
}
|
||||
""" }}
|
||||
}
|
||||
|
||||
licenses {
|
||||
${licenses.joinToString("\n") { """
|
||||
license {
|
||||
name = "${it.title}"
|
||||
url = "${it.url}"
|
||||
}
|
||||
""" }}
|
||||
}
|
||||
}
|
||||
repositories {
|
||||
${repositories.joinToString("\n ") { it.build(" ") }}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
${gpgSigning.generateMavenConfig()}
|
||||
""".trimIndent()
|
@@ -1,21 +1,21 @@
|
||||
package dev.inmo.kmppscriptbuilder.core.export.jvm_only
|
||||
|
||||
import dev.inmo.kmppscriptbuilder.core.export.generateMavenConfig
|
||||
import dev.inmo.kmppscriptbuilder.core.models.*
|
||||
|
||||
fun MavenConfig.buildJvmOnlyMavenConfig(licenses: List<License>): String = """
|
||||
apply plugin: 'maven-publish'
|
||||
${if (includeGpgSigning) "apply plugin: 'signing'\n" else ""}
|
||||
apply plugin: 'maven-publish'
|
||||
|
||||
task javadocJar(type: Jar) {
|
||||
task javadocJar(type: Jar) {
|
||||
from javadoc
|
||||
classifier = 'javadoc'
|
||||
}
|
||||
task sourcesJar(type: Jar) {
|
||||
}
|
||||
task sourcesJar(type: Jar) {
|
||||
from sourceSets.main.allSource
|
||||
classifier = 'sources'
|
||||
}
|
||||
}
|
||||
|
||||
publishing {
|
||||
publishing {
|
||||
publications {
|
||||
maven(MavenPublication) {
|
||||
from components.java
|
||||
@@ -59,11 +59,6 @@ fun MavenConfig.buildJvmOnlyMavenConfig(licenses: List<License>): String = """
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
${if (includeGpgSigning) """
|
||||
signing {
|
||||
useGpgCmd()
|
||||
sign publishing.publications
|
||||
}
|
||||
""" else ""}
|
||||
}
|
||||
${gpgSigning.generateMavenConfig()}
|
||||
""".trimIndent()
|
@@ -1,15 +1,16 @@
|
||||
package dev.inmo.kmppscriptbuilder.core.export.mpp
|
||||
|
||||
import dev.inmo.kmppscriptbuilder.core.export.generateMavenConfig
|
||||
import dev.inmo.kmppscriptbuilder.core.models.*
|
||||
|
||||
fun MavenConfig.buildMultiplatformMavenConfig(licenses: List<License>): String = """
|
||||
apply plugin: 'maven-publish'
|
||||
${if (includeGpgSigning) "apply plugin: 'signing'\n" else ""}
|
||||
task javadocsJar(type: Jar) {
|
||||
classifier = 'javadoc'
|
||||
}
|
||||
apply plugin: 'maven-publish'
|
||||
|
||||
publishing {
|
||||
task javadocsJar(type: Jar) {
|
||||
classifier = 'javadoc'
|
||||
}
|
||||
|
||||
publishing {
|
||||
publications.all {
|
||||
artifact javadocsJar
|
||||
|
||||
@@ -46,11 +47,6 @@ fun MavenConfig.buildMultiplatformMavenConfig(licenses: List<License>): String =
|
||||
${repositories.joinToString("\n ") { it.build(" ") }}
|
||||
}
|
||||
}
|
||||
}
|
||||
${if (includeGpgSigning) """
|
||||
signing {
|
||||
useGpgCmd()
|
||||
sign publishing.publications
|
||||
}
|
||||
""" else ""}
|
||||
}
|
||||
${gpgSigning.generateMavenConfig()}
|
||||
""".trimIndent()
|
@@ -1,5 +1,6 @@
|
||||
package dev.inmo.kmppscriptbuilder.core.models
|
||||
|
||||
import dev.inmo.kmppscriptbuilder.core.export.js_only.buildJsOnlyMavenConfig
|
||||
import dev.inmo.kmppscriptbuilder.core.export.jvm_only.buildJvmOnlyMavenConfig
|
||||
import dev.inmo.kmppscriptbuilder.core.export.mpp.buildMultiplatformMavenConfig
|
||||
import kotlinx.serialization.*
|
||||
@@ -32,12 +33,6 @@ object ProjectTypeSerializer : KSerializer<ProjectType> {
|
||||
|
||||
object MultiplatformProjectType : ProjectType() {
|
||||
override val name: String = "Multiplatform"
|
||||
// override fun buildBintrayGradleConfig(
|
||||
// bintrayConfig: BintrayConfig,
|
||||
// licenses: List<License>
|
||||
// ): String = bintrayConfig.buildMultiplatformGradleConfig(
|
||||
// licenses
|
||||
// )
|
||||
|
||||
override fun buildMavenGradleConfig(
|
||||
mavenConfig: MavenConfig,
|
||||
@@ -49,12 +44,6 @@ object MultiplatformProjectType : ProjectType() {
|
||||
|
||||
object JVMProjectType : ProjectType() {
|
||||
override val name: String = "JVM"
|
||||
// override fun buildBintrayGradleConfig(
|
||||
// bintrayConfig: BintrayConfig,
|
||||
// licenses: List<License>
|
||||
// ): String = bintrayConfig.buildJvmOnlyGradleConfig(
|
||||
// licenses
|
||||
// )
|
||||
|
||||
override fun buildMavenGradleConfig(
|
||||
mavenConfig: MavenConfig,
|
||||
@@ -64,6 +53,15 @@ object JVMProjectType : ProjectType() {
|
||||
)
|
||||
}
|
||||
|
||||
object JSProjectType : ProjectType() {
|
||||
override val name: String = "JS"
|
||||
|
||||
override fun buildMavenGradleConfig(
|
||||
mavenConfig: MavenConfig,
|
||||
licenses: List<License>
|
||||
): String = mavenConfig.buildJsOnlyMavenConfig(licenses)
|
||||
}
|
||||
|
||||
@Serializable
|
||||
data class Config(
|
||||
val licenses: List<License>,
|
||||
|
@@ -30,19 +30,19 @@ suspend fun HttpClient.getLicenses(): Map<String, License> {
|
||||
|
||||
suspend fun HttpClient.searchLicense(name: String): List<License> {
|
||||
val licenses = licenses ?: getLicenses()
|
||||
val lowerCase = name.toLowerCase()
|
||||
val upperCase = name.toUpperCase()
|
||||
val lowerCase = name.lowercase()
|
||||
val upperCase = name.uppercase()
|
||||
return licenses.values.filter {
|
||||
it.title.toLowerCase().contains(lowerCase) || it.title.toUpperCase().contains(upperCase) || it.title.contains(name)
|
||||
|| it.id.toLowerCase().contains(lowerCase) || it.id.toUpperCase().contains(upperCase) || it.id.contains(name)
|
||||
it.title.lowercase().contains(lowerCase) || it.title.uppercase().contains(upperCase) || it.title.contains(name)
|
||||
|| it.id.lowercase().contains(lowerCase) || it.id.uppercase().contains(upperCase) || it.id.contains(name)
|
||||
}
|
||||
}
|
||||
|
||||
fun Map<String, License>.searchLicense(name: String): List<License> {
|
||||
val lowerCase = name.toLowerCase()
|
||||
val upperCase = name.toUpperCase()
|
||||
val lowerCase = name.lowercase()
|
||||
val upperCase = name.uppercase()
|
||||
return values.filter {
|
||||
it.title.toLowerCase().contains(lowerCase) || it.title.toUpperCase().contains(upperCase) || it.title.contains(name)
|
||||
|| it.id.toLowerCase().contains(lowerCase) || it.id.toUpperCase().contains(upperCase) || it.id.contains(name)
|
||||
it.title.lowercase().contains(lowerCase) || it.title.uppercase().contains(upperCase) || it.title.contains(name)
|
||||
|| it.id.lowercase().contains(lowerCase) || it.id.uppercase().contains(upperCase) || it.id.contains(name)
|
||||
}
|
||||
}
|
||||
|
@@ -2,15 +2,30 @@ package dev.inmo.kmppscriptbuilder.core.models
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
const val defaultProjectName = "\${project.name}"
|
||||
const val defaultProjectDescription = "\${project.name}"
|
||||
|
||||
@Serializable
|
||||
sealed class GpgSigning {
|
||||
@Serializable
|
||||
object Disabled : GpgSigning()
|
||||
@Serializable
|
||||
object Optional : GpgSigning()
|
||||
@Serializable
|
||||
object Enabled : GpgSigning()
|
||||
}
|
||||
|
||||
@Serializable
|
||||
data class MavenConfig(
|
||||
val name: String,
|
||||
val description: String,
|
||||
val url: String,
|
||||
val vcsUrl: String,
|
||||
val includeGpgSigning: Boolean = false,
|
||||
val developers: List<Developer>,
|
||||
val repositories: List<MavenPublishingRepository> = emptyList()
|
||||
val repositories: List<MavenPublishingRepository> = emptyList(),
|
||||
val gpgSigning: GpgSigning = GpgSigning.Disabled,
|
||||
@Deprecated("Replaced with gpgSigning")
|
||||
val includeGpgSigning: Boolean = false,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
@@ -22,14 +37,20 @@ data class MavenPublishingRepository(
|
||||
name.toUpperCase()
|
||||
}
|
||||
|
||||
fun build(indent: String) = """maven {
|
||||
fun build(indent: String): String {
|
||||
val usernameProperty = "${nameCapitalized}_USER"
|
||||
val passwordProperty = "${nameCapitalized}_PASSWORD"
|
||||
return """if ((project.hasProperty('${usernameProperty}') || System.getenv('${usernameProperty}') != null) && (project.hasProperty('${passwordProperty}') || System.getenv('${passwordProperty}') != null)) {
|
||||
maven {
|
||||
name = "$name"
|
||||
url = uri("$url")
|
||||
credentials {
|
||||
username = project.hasProperty('${nameCapitalized}_USER') ? project.property('${nameCapitalized}_USER') : System.getenv('${nameCapitalized}_USER')
|
||||
password = project.hasProperty('${nameCapitalized}_PASSWORD') ? project.property('${nameCapitalized}_PASSWORD') : System.getenv('${nameCapitalized}_PASSWORD')
|
||||
username = project.hasProperty('${usernameProperty}') ? project.property('${usernameProperty}') : System.getenv('${usernameProperty}')
|
||||
password = project.hasProperty('${passwordProperty}') ? project.property('${passwordProperty}') : System.getenv('${passwordProperty}')
|
||||
}
|
||||
}
|
||||
}""".replace("\n", "\n$indent")
|
||||
}
|
||||
}
|
||||
|
||||
val SonatypeRepository = MavenPublishingRepository("sonatype", "https://oss.sonatype.org/service/local/staging/deploy/maven2/")
|
||||
|
@@ -10,7 +10,6 @@ kotlin {
|
||||
jvm {
|
||||
compilations.main.kotlinOptions {
|
||||
jvmTarget = "11"
|
||||
useIR = true
|
||||
}
|
||||
}
|
||||
sourceSets {
|
||||
|
@@ -1,20 +1,24 @@
|
||||
package dev.inmo.kmppscriptbuilder.desktop
|
||||
|
||||
import androidx.compose.desktop.Window
|
||||
import androidx.compose.foundation.*
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.material.*
|
||||
import androidx.compose.material.Colors
|
||||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import dev.inmo.kmppscriptbuilder.desktop.utils.*
|
||||
import dev.inmo.kmppscriptbuilder.desktop.views.*
|
||||
import androidx.compose.ui.window.Window
|
||||
import androidx.compose.ui.window.application
|
||||
import dev.inmo.kmppscriptbuilder.desktop.utils.init
|
||||
import dev.inmo.kmppscriptbuilder.desktop.utils.loadConfigFile
|
||||
import dev.inmo.kmppscriptbuilder.desktop.views.BuilderView
|
||||
import java.io.File
|
||||
|
||||
//private val uncaughtExceptionsBC = BroadcastChannel<DefaultErrorHandler.ErrorEvent>(Channel.CONFLATED)
|
||||
//val uncaughtExceptionsFlow: Flow<DefaultErrorHandler.ErrorEvent> = uncaughtExceptionsBC.asFlow()
|
||||
|
||||
fun main(args: Array<String>) = Window(title = "Kotlin Multiplatform Publishing Builder") {
|
||||
fun main(args: Array<String>) = application {
|
||||
Window(onCloseRequest = ::exitApplication, title = "Kotlin Multiplatform Publishing Builder") {
|
||||
val builder = BuilderView()
|
||||
MaterialTheme(
|
||||
Colors(
|
||||
@@ -59,4 +63,5 @@ fun main(args: Array<String>) = Window(title = "Kotlin Multiplatform Publishing
|
||||
val config = loadConfigFile(File(args.first()))
|
||||
builder.config = config
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,17 @@
|
||||
package dev.inmo.kmppscriptbuilder.desktop.utils
|
||||
|
||||
import java.awt.Desktop
|
||||
import java.net.URI
|
||||
|
||||
fun openLink(link: String): Boolean {
|
||||
val desktop = if (Desktop.isDesktopSupported()) Desktop.getDesktop() else null
|
||||
if (desktop != null && desktop.isSupported(Desktop.Action.BROWSE)) {
|
||||
try {
|
||||
desktop.browse(URI(link))
|
||||
return true
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
@@ -6,7 +6,7 @@ import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.material.*
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.svgResource
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import dev.inmo.kmppscriptbuilder.core.models.Config
|
||||
import dev.inmo.kmppscriptbuilder.desktop.utils.*
|
||||
@@ -45,7 +45,7 @@ class BuilderView : View() {
|
||||
}
|
||||
) {
|
||||
Image(
|
||||
painter = svgResource("images/open_file.svg"),
|
||||
painter = painterResource("images/open_file.svg"),
|
||||
contentDescription = "Open file"
|
||||
)
|
||||
}
|
||||
@@ -57,7 +57,7 @@ class BuilderView : View() {
|
||||
}
|
||||
) {
|
||||
Image(
|
||||
painter = svgResource("images/save_file.svg"),
|
||||
painter = painterResource("images/save_file.svg"),
|
||||
contentDescription = "Save file"
|
||||
)
|
||||
}
|
||||
@@ -70,7 +70,7 @@ class BuilderView : View() {
|
||||
}
|
||||
) {
|
||||
Image(
|
||||
painter = svgResource("images/export_gradle.svg"),
|
||||
painter = painterResource("images/export_gradle.svg"),
|
||||
contentDescription = "Export Gradle script"
|
||||
)
|
||||
}
|
||||
@@ -84,7 +84,7 @@ class BuilderView : View() {
|
||||
}
|
||||
) {
|
||||
Image(
|
||||
painter = svgResource("images/save_as.svg"),
|
||||
painter = painterResource("images/save_as.svg"),
|
||||
contentDescription = "Export Gradle script"
|
||||
)
|
||||
}
|
||||
|
@@ -2,7 +2,7 @@ package dev.inmo.kmppscriptbuilder.desktop.views
|
||||
|
||||
import androidx.compose.runtime.*
|
||||
import dev.inmo.kmppscriptbuilder.core.models.Developer
|
||||
import dev.inmo.kmppscriptbuilder.desktop.utils.*
|
||||
import dev.inmo.kmppscriptbuilder.desktop.utils.CommonTextField
|
||||
|
||||
class DeveloperState(
|
||||
id: String = "",
|
||||
|
@@ -53,7 +53,7 @@ class LicensesView: VerticalView("Licenses") {
|
||||
licensesOffersToShow.clear()
|
||||
if (licenseSearchFilter.isNotEmpty()) {
|
||||
licensesOffersToShow.addAll(
|
||||
availableLicensesState.filter { filterText.all { symbol -> symbol.toLowerCase() in it.title } }
|
||||
availableLicensesState.filter { filterText.all { symbol -> symbol.lowercaseChar() in it.title } }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@@ -1,11 +1,13 @@
|
||||
package dev.inmo.kmppscriptbuilder.desktop.views
|
||||
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.material.*
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.material.Button
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.mutableStateListOf
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
import dev.inmo.kmppscriptbuilder.desktop.utils.*
|
||||
import dev.inmo.kmppscriptbuilder.desktop.utils.CommonText
|
||||
import dev.inmo.kmppscriptbuilder.desktop.utils.VerticalView
|
||||
|
||||
abstract class ListView<T>(title: String) : VerticalView(title) {
|
||||
protected val itemsList = mutableStateListOf<T>()
|
||||
|
@@ -2,8 +2,7 @@ package dev.inmo.kmppscriptbuilder.desktop.views
|
||||
|
||||
import androidx.compose.foundation.layout.ColumnScope
|
||||
import androidx.compose.runtime.*
|
||||
import dev.inmo.kmppscriptbuilder.core.models.MavenConfig
|
||||
import dev.inmo.kmppscriptbuilder.core.models.SonatypeRepository
|
||||
import dev.inmo.kmppscriptbuilder.core.models.*
|
||||
import dev.inmo.kmppscriptbuilder.desktop.utils.*
|
||||
|
||||
class MavenInfoView : VerticalView("Project information") {
|
||||
@@ -11,31 +10,35 @@ class MavenInfoView : VerticalView("Project information") {
|
||||
private var projectDescriptionProperty by mutableStateOf("")
|
||||
private var projectUrlProperty by mutableStateOf("")
|
||||
private var projectVcsUrlProperty by mutableStateOf("")
|
||||
private var includeGpgSignProperty by mutableStateOf(true)
|
||||
private var gpgSignProperty by mutableStateOf<GpgSigning>(GpgSigning.Disabled)
|
||||
private var publishToMavenCentralProperty by mutableStateOf(false)
|
||||
private val developersView = DevelopersView()
|
||||
private val repositoriesView = RepositoriesView()
|
||||
|
||||
var mavenConfig: MavenConfig
|
||||
get() = MavenConfig(
|
||||
projectNameProperty,
|
||||
projectDescriptionProperty,
|
||||
projectNameProperty.ifBlank { defaultProjectName },
|
||||
projectDescriptionProperty.ifBlank { defaultProjectDescription },
|
||||
projectUrlProperty,
|
||||
projectVcsUrlProperty,
|
||||
includeGpgSignProperty,
|
||||
developersView.developers,
|
||||
repositoriesView.repositories + if (publishToMavenCentralProperty) {
|
||||
listOf(SonatypeRepository)
|
||||
} else {
|
||||
emptyList()
|
||||
}
|
||||
},
|
||||
gpgSignProperty
|
||||
)
|
||||
set(value) {
|
||||
projectNameProperty = value.name
|
||||
projectDescriptionProperty = value.description
|
||||
projectUrlProperty = value.url
|
||||
projectVcsUrlProperty = value.vcsUrl
|
||||
includeGpgSignProperty = value.includeGpgSigning
|
||||
gpgSignProperty = if (value.includeGpgSigning) {
|
||||
GpgSigning.Enabled
|
||||
} else {
|
||||
value.gpgSigning
|
||||
}
|
||||
publishToMavenCentralProperty = value.repositories.any { it == SonatypeRepository }
|
||||
developersView.developers = value.developers
|
||||
repositoriesView.repositories = value.repositories.filter { it != SonatypeRepository }
|
||||
@@ -60,11 +63,12 @@ class MavenInfoView : VerticalView("Project information") {
|
||||
"Public project VCS URL (with .git)"
|
||||
) { projectVcsUrlProperty = it }
|
||||
|
||||
SwitchWithLabel(
|
||||
"Include GPG Signing",
|
||||
includeGpgSignProperty,
|
||||
placeSwitchAtTheStart = true
|
||||
) { includeGpgSignProperty = it }
|
||||
|
||||
// SwitchWithLabel(
|
||||
// "Include GPG Signing",
|
||||
// includeGpgSignProperty,
|
||||
// placeSwitchAtTheStart = true
|
||||
// ) { includeGpgSignProperty = it }
|
||||
|
||||
SwitchWithLabel(
|
||||
"Include publication to MavenCentral",
|
||||
|
@@ -2,7 +2,7 @@ package dev.inmo.kmppscriptbuilder.desktop.views
|
||||
|
||||
import androidx.compose.runtime.*
|
||||
import dev.inmo.kmppscriptbuilder.core.models.MavenPublishingRepository
|
||||
import dev.inmo.kmppscriptbuilder.desktop.utils.*
|
||||
import dev.inmo.kmppscriptbuilder.desktop.utils.CommonTextField
|
||||
|
||||
class RepositoryState(
|
||||
name: String = "",
|
||||
|
@@ -15,6 +15,7 @@ allprojects {
|
||||
|
||||
mppProjectWithSerializationPresetPath = "${rootProject.projectDir.absolutePath}/mppProjectWithSerialization.gradle"
|
||||
mppJavaProjectPresetPath = "${rootProject.projectDir.absolutePath}/mppJavaProject.gradle"
|
||||
mppJsProjectPresetPath = "${rootProject.projectDir.absolutePath}/mppJsProject.gradle"
|
||||
mppAndroidProjectPresetPath = "${rootProject.projectDir.absolutePath}/mppAndroidProject.gradle"
|
||||
|
||||
defaultAndroidSettingsPresetPath = "${rootProject.projectDir.absolutePath}/defaultAndroidSettings.gradle"
|
||||
|
@@ -6,27 +6,27 @@ kotlin.incremental.js=true
|
||||
android.useAndroidX=true
|
||||
android.enableJetifier=true
|
||||
|
||||
kotlin_version=1.4.30
|
||||
kotlin_coroutines_version=1.4.2
|
||||
kotlin_serialisation_core_version=1.1.0
|
||||
ktor_version=1.5.1
|
||||
micro_utils_version=0.4.27
|
||||
kotlin_version=1.6.10
|
||||
kotlin_coroutines_version=1.6.0
|
||||
kotlin_serialisation_core_version=1.3.2
|
||||
ktor_version=1.6.7
|
||||
micro_utils_version=0.9.0
|
||||
|
||||
compose_version=0.3.0
|
||||
compose_version=1.0.1
|
||||
|
||||
# ANDROID
|
||||
|
||||
android_minSdkVersion=21
|
||||
android_compileSdkVersion=30
|
||||
android_buildToolsVersion=30.0.2
|
||||
dexcount_version=2.0.0
|
||||
android_compileSdkVersion=32
|
||||
android_buildToolsVersion=32.0.0
|
||||
dexcount_version=3.0.1
|
||||
junit_version=4.12
|
||||
test_ext_junit_version=1.1.2
|
||||
espresso_core=3.3.0
|
||||
|
||||
# Dokka
|
||||
|
||||
dokka_version=1.4.20
|
||||
dokka_version=1.6.0
|
||||
|
||||
# Project data
|
||||
|
||||
|
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.8-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-bin.zip
|
||||
|
@@ -1,4 +1,4 @@
|
||||
project.version = "$version" + System.getenv("additional_version")
|
||||
project.version = "$version" + (System.getenv("additional_version") != null ? System.getenv("additional_version") : "")
|
||||
project.group = "$group"
|
||||
|
||||
// apply from: "$publishGradlePath"
|
||||
|
@@ -1,4 +1,4 @@
|
||||
project.version = "$version" + System.getenv("additional_version")
|
||||
project.version = "$version" + (System.getenv("additional_version") != null ? System.getenv("additional_version") : "")
|
||||
project.group = "$group"
|
||||
|
||||
// apply from: "$publishGradlePath"
|
||||
|
34
mppJsProject.gradle
Normal file
34
mppJsProject.gradle
Normal file
@@ -0,0 +1,34 @@
|
||||
project.version = "$version" + (System.getenv("additional_version") != null ? System.getenv("additional_version") : "")
|
||||
project.group = "$group"
|
||||
|
||||
// apply from: "$publishGradlePath"
|
||||
|
||||
kotlin {
|
||||
js (IR) {
|
||||
browser {
|
||||
binaries.executable()
|
||||
}
|
||||
nodejs()
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
commonMain {
|
||||
dependencies {
|
||||
implementation kotlin('stdlib')
|
||||
api "org.jetbrains.kotlinx:kotlinx-serialization-json:$kotlin_serialisation_core_version"
|
||||
}
|
||||
}
|
||||
commonTest {
|
||||
dependencies {
|
||||
implementation kotlin('test-common')
|
||||
implementation kotlin('test-annotations-common')
|
||||
}
|
||||
}
|
||||
jsTest {
|
||||
dependencies {
|
||||
implementation kotlin('test-js')
|
||||
implementation kotlin('test-junit')
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -9,7 +9,8 @@ rootProject.name = 'kmppscriptbuilder'
|
||||
|
||||
String[] includes = [
|
||||
":core",
|
||||
":desktop"
|
||||
":desktop",
|
||||
":web"
|
||||
]
|
||||
|
||||
|
||||
|
17
web/build.gradle
Normal file
17
web/build.gradle
Normal file
@@ -0,0 +1,17 @@
|
||||
plugins {
|
||||
id "org.jetbrains.kotlin.multiplatform"
|
||||
id "org.jetbrains.kotlin.plugin.serialization"
|
||||
}
|
||||
|
||||
apply from: "$mppJsProjectPresetPath"
|
||||
|
||||
kotlin {
|
||||
sourceSets {
|
||||
commonMain {
|
||||
dependencies {
|
||||
implementation project(":kmppscriptbuilder.core")
|
||||
implementation "dev.inmo:micro_utils.common:$micro_utils_version"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
82
web/src/jsMain/kotlin/dev/inmo/kmppscriptbuilder/web/main.kt
Normal file
82
web/src/jsMain/kotlin/dev/inmo/kmppscriptbuilder/web/main.kt
Normal file
@@ -0,0 +1,82 @@
|
||||
package dev.inmo.kmppscriptbuilder.web
|
||||
|
||||
import dev.inmo.kmppscriptbuilder.core.models.Config
|
||||
import dev.inmo.kmppscriptbuilder.core.utils.serialFormat
|
||||
import dev.inmo.kmppscriptbuilder.web.views.*
|
||||
import kotlinx.browser.document
|
||||
import kotlinx.dom.appendElement
|
||||
import org.w3c.dom.*
|
||||
import org.w3c.dom.url.URL
|
||||
import org.w3c.files.*
|
||||
|
||||
fun saveFile(content: String, filename: String) {
|
||||
val a = document.body!!.appendElement("a") {
|
||||
setAttribute("style", "visibility:hidden; display: none")
|
||||
} as HTMLAnchorElement
|
||||
val blob = Blob(arrayOf(content), BlobPropertyBag(
|
||||
"application/*;charset=utf-8"
|
||||
))
|
||||
val url = URL.createObjectURL(blob)
|
||||
a.href = url
|
||||
a.download = filename
|
||||
a.click()
|
||||
URL.revokeObjectURL(url)
|
||||
a.remove()
|
||||
}
|
||||
|
||||
fun main() {
|
||||
document.addEventListener(
|
||||
"DOMContentLoaded",
|
||||
{
|
||||
val builderView = BuilderView()
|
||||
|
||||
(document.getElementById("openConfig") as HTMLElement).onclick = {
|
||||
val targetInput = document.body!!.appendElement("input") {
|
||||
setAttribute("style", "visibility:hidden; display: none")
|
||||
} as HTMLInputElement
|
||||
targetInput.type = "file"
|
||||
targetInput.onchange = {
|
||||
targetInput.files ?.also { files ->
|
||||
for (i in (0 until files.length) ) {
|
||||
files[i] ?.also { file ->
|
||||
val reader = FileReader()
|
||||
|
||||
reader.onload = {
|
||||
val content = it.target.asDynamic().result as String
|
||||
builderView.config = serialFormat.decodeFromString(Config.serializer(), content)
|
||||
false
|
||||
}
|
||||
|
||||
reader.readAsText(file)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
targetInput.click()
|
||||
targetInput.remove()
|
||||
false
|
||||
}
|
||||
(document.getElementById("saveConfig") as HTMLElement).onclick = {
|
||||
val filename = "publish.kpsb"
|
||||
val content = serialFormat.encodeToString(Config.serializer(), builderView.config)
|
||||
|
||||
saveFile(content, filename)
|
||||
|
||||
false
|
||||
}
|
||||
(document.getElementById("exportScript") as HTMLElement).onclick = {
|
||||
val filename = "publish.gradle"
|
||||
|
||||
val content = builderView.config.run {
|
||||
type.buildMavenGradleConfig(
|
||||
mavenConfig,
|
||||
licenses
|
||||
)
|
||||
}
|
||||
|
||||
saveFile(content, filename)
|
||||
false
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
@@ -0,0 +1,13 @@
|
||||
package dev.inmo.kmppscriptbuilder.web.utils
|
||||
|
||||
import org.w3c.dom.HTMLElement
|
||||
|
||||
var HTMLElement.ukActive: Boolean
|
||||
get() = classList.contains("uk-active")
|
||||
set(value) {
|
||||
if (value) {
|
||||
classList.add("uk-active")
|
||||
} else {
|
||||
classList.remove("uk-active")
|
||||
}
|
||||
}
|
@@ -0,0 +1,10 @@
|
||||
package dev.inmo.kmppscriptbuilder.web.utils
|
||||
|
||||
import kotlinx.browser.document
|
||||
|
||||
inline fun <R> keepScrolling(crossinline block: () -> R): R = document.body ?.let {
|
||||
val (x, y) = (it.scrollLeft to it.scrollTop)
|
||||
return block().also { _ ->
|
||||
it.scrollTo(x, y)
|
||||
}
|
||||
} ?: block()
|
@@ -0,0 +1,23 @@
|
||||
package dev.inmo.kmppscriptbuilder.web.views
|
||||
|
||||
import dev.inmo.kmppscriptbuilder.core.models.Config
|
||||
import kotlinx.browser.document
|
||||
import org.w3c.dom.HTMLElement
|
||||
|
||||
class BuilderView : View {
|
||||
private val projectTypeView = ProjectTypeView()
|
||||
private val licensesView = LicensesView(document.getElementById("licensesListDiv") as HTMLElement)
|
||||
private val mavenInfoTypeView = MavenProjectInfoView()
|
||||
|
||||
var config: Config
|
||||
get() = Config(
|
||||
licensesView.licenses,
|
||||
mavenInfoTypeView.mavenConfig,
|
||||
projectTypeView.projectType
|
||||
)
|
||||
set(value) {
|
||||
licensesView.licenses = value.licenses
|
||||
mavenInfoTypeView.mavenConfig = value.mavenConfig
|
||||
projectTypeView.projectType = value.type
|
||||
}
|
||||
}
|
@@ -0,0 +1,35 @@
|
||||
package dev.inmo.kmppscriptbuilder.web.views
|
||||
|
||||
import dev.inmo.kmppscriptbuilder.core.models.Developer
|
||||
import org.w3c.dom.*
|
||||
|
||||
class DevelopersView(rootElement: HTMLElement) : MutableListView<Developer>(rootElement, "Add developer", "Remove developer") {
|
||||
private val HTMLElement.usernameElement: HTMLInputElement
|
||||
get() = getElementsByTagName("input")[0] as HTMLInputElement
|
||||
private val HTMLElement.nameElement: HTMLInputElement
|
||||
get() = getElementsByTagName("input")[1] as HTMLInputElement
|
||||
private val HTMLElement.emailElement: HTMLInputElement
|
||||
get() = getElementsByTagName("input")[2] as HTMLInputElement
|
||||
|
||||
var developers: List<Developer>
|
||||
get() = elements.map {
|
||||
Developer(it.usernameElement.value, it.nameElement.value, it.emailElement.value)
|
||||
}
|
||||
set(value) {
|
||||
data = value
|
||||
}
|
||||
|
||||
override fun createPlainObject(): Developer = Developer("", "", "")
|
||||
|
||||
override fun HTMLElement.addContentBeforeRemoveButton(value: Developer) {
|
||||
createTextField("Developer ID", "Developer username").value = value.id
|
||||
createTextField("Developer name", "").value = value.name
|
||||
createTextField("Developer E-Mail", "").value = value.eMail
|
||||
}
|
||||
|
||||
override fun HTMLElement.updateElement(from: Developer, to: Developer) {
|
||||
usernameElement.value = to.id
|
||||
nameElement.value = to.name
|
||||
emailElement.value = to.eMail
|
||||
}
|
||||
}
|
@@ -0,0 +1,113 @@
|
||||
package dev.inmo.kmppscriptbuilder.web.views
|
||||
|
||||
import dev.inmo.kmppscriptbuilder.core.models.License
|
||||
import dev.inmo.kmppscriptbuilder.core.models.getLicenses
|
||||
import dev.inmo.micro_utils.coroutines.safeActor
|
||||
import dev.inmo.micro_utils.coroutines.subscribeSafelyWithoutExceptions
|
||||
import io.ktor.client.HttpClient
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.channels.Channel
|
||||
import kotlinx.coroutines.channels.SendChannel
|
||||
import kotlinx.coroutines.flow.consumeAsFlow
|
||||
import kotlinx.coroutines.flow.debounce
|
||||
import kotlinx.dom.appendElement
|
||||
import org.w3c.dom.*
|
||||
|
||||
class LicensesView(
|
||||
rootElement: HTMLElement,
|
||||
client: HttpClient = HttpClient(),
|
||||
scope: CoroutineScope = CoroutineScope(Dispatchers.Default)
|
||||
) : MutableListView<License>(rootElement, "Add empty license", "Remove license") {
|
||||
private val HTMLElement.idElement: HTMLInputElement
|
||||
get() = getElementsByTagName("input")[0] as HTMLInputElement
|
||||
private val HTMLElement.titleElement: HTMLInputElement
|
||||
get() = getElementsByTagName("input")[1] as HTMLInputElement
|
||||
private val HTMLElement.urlElement: HTMLInputElement
|
||||
get() = getElementsByTagName("input")[2] as HTMLInputElement
|
||||
|
||||
private class LicenseOfferList(
|
||||
rootElement: HTMLElement,
|
||||
private val licensesView: LicensesView,
|
||||
client: HttpClient,
|
||||
scope: CoroutineScope
|
||||
) : ListView<License>(rootElement, useSimpleDiffStrategy = true) {
|
||||
private var licensesTemplates: List<License> = emptyList()
|
||||
|
||||
init {
|
||||
scope.launch {
|
||||
licensesTemplates = client.getLicenses().values.toList()
|
||||
changeActor.send(Unit) // update list of searches
|
||||
}
|
||||
}
|
||||
|
||||
private val changeActor: SendChannel<Unit> = scope.run {
|
||||
val onChangeActor = Channel<Unit>(Channel.CONFLATED)
|
||||
onChangeActor.consumeAsFlow().subscribeSafelyWithoutExceptions(scope) {
|
||||
val lowercased = searchString
|
||||
data = if (lowercased.isEmpty()) {
|
||||
emptyList()
|
||||
} else {
|
||||
licensesTemplates.filter {
|
||||
val lowercasedTitle = it.title.lowercase()
|
||||
lowercased.all { it in lowercasedTitle }
|
||||
}
|
||||
}
|
||||
}
|
||||
onChangeActor
|
||||
}
|
||||
private val searchElement = rootElement.createTextField("Quick add", "Type some license name part to find it").apply {
|
||||
oninput = {
|
||||
changeActor.trySend(Unit)
|
||||
false
|
||||
}
|
||||
}
|
||||
private var searchString: String
|
||||
get() = searchElement.value.lowercase()
|
||||
set(value) {
|
||||
searchElement.value = value
|
||||
}
|
||||
|
||||
override fun HTMLElement.placeElement(value: License) {
|
||||
createCommonButton(value.title).onclick = {
|
||||
searchString = ""
|
||||
licensesView.licenses += value
|
||||
changeActor.trySend(Unit)
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
override fun HTMLElement.updateElement(from: License, to: License) {
|
||||
getElementsByTagName("button")[0] ?.remove()
|
||||
placeElement(to)
|
||||
}
|
||||
}
|
||||
|
||||
private val licensesOffersList = LicenseOfferList(
|
||||
rootElement.appendElement("div") { classList.add("uk-padding-small") } as HTMLElement,
|
||||
this,
|
||||
client,
|
||||
scope
|
||||
)
|
||||
|
||||
var licenses: List<License>
|
||||
get() = elements.map {
|
||||
License(it.idElement.value, it.titleElement.value, it.urlElement.value)
|
||||
}
|
||||
set(value) {
|
||||
data = value
|
||||
}
|
||||
|
||||
override fun createPlainObject(): License = License("", "", "")
|
||||
|
||||
override fun HTMLElement.addContentBeforeRemoveButton(value: License) {
|
||||
createTextField("License Id", "Short name like \"Apache-2.0\"").value = value.id
|
||||
createTextField("License Title", "Official title of license (like \"Apache Software License 2.0\")").value = value.title
|
||||
createTextField("License URL", "Link to your LICENSE file OR official license file (like \"https://opensource.org/licenses/Apache-2.0\")").value = value.url ?: ""
|
||||
}
|
||||
|
||||
override fun HTMLElement.updateElement(from: License, to: License) {
|
||||
idElement.value = to.id
|
||||
titleElement.value = to.title
|
||||
urlElement.value = to.url ?: ""
|
||||
}
|
||||
}
|
@@ -0,0 +1,58 @@
|
||||
package dev.inmo.kmppscriptbuilder.web.views
|
||||
|
||||
import dev.inmo.micro_utils.common.calculateStrictDiff
|
||||
import kotlinx.dom.appendElement
|
||||
import org.w3c.dom.HTMLElement
|
||||
|
||||
abstract class ListView<T>(
|
||||
protected val rootElement: HTMLElement,
|
||||
useSimpleDiffStrategy: Boolean = false
|
||||
) : View {
|
||||
protected val elements = mutableListOf<HTMLElement>()
|
||||
private val diffHandling: (old: List<T>, new: List<T>) -> Unit = if (useSimpleDiffStrategy) {
|
||||
{ _, new ->
|
||||
elements.forEach { it.remove() }
|
||||
elements.clear()
|
||||
new.forEach {
|
||||
val element = instantiateElement()
|
||||
elements.add(element)
|
||||
element.placeElement(it)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
{ old, new ->
|
||||
val diff = old.calculateStrictDiff(new)
|
||||
diff.removed.forEach {
|
||||
elements[it.index].remove()
|
||||
elements.removeAt(it.index)
|
||||
println(it.value)
|
||||
}
|
||||
diff.added.forEach {
|
||||
val element = instantiateElement()
|
||||
elements.add(element)
|
||||
element.placeElement(it.value)
|
||||
}
|
||||
diff.replaced.forEach { (old, new) ->
|
||||
val element = elements.getOrNull(old.index) ?.also { it.updateElement(old.value, new.value) }
|
||||
if (element == null) {
|
||||
val newElement = instantiateElement()
|
||||
newElement.placeElement(new.value)
|
||||
elements[new.index] = newElement
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
protected var data: List<T> = emptyList()
|
||||
set(value) {
|
||||
val old = field
|
||||
field = value
|
||||
diffHandling(old, value)
|
||||
}
|
||||
|
||||
protected abstract fun HTMLElement.placeElement(value: T)
|
||||
protected abstract fun HTMLElement.updateElement(from: T, to: T)
|
||||
|
||||
private fun instantiateElement() = rootElement.appendElement("div") {
|
||||
classList.add("uk-padding-small")
|
||||
} as HTMLElement
|
||||
}
|
@@ -0,0 +1,82 @@
|
||||
package dev.inmo.kmppscriptbuilder.web.views
|
||||
|
||||
import dev.inmo.kmppscriptbuilder.core.models.*
|
||||
import dev.inmo.kmppscriptbuilder.web.utils.ukActive
|
||||
import kotlinx.browser.document
|
||||
import org.w3c.dom.HTMLElement
|
||||
import org.w3c.dom.HTMLInputElement
|
||||
|
||||
class MavenProjectInfoView : View {
|
||||
private val nameElement = document.getElementById("projectNameInput") as HTMLInputElement
|
||||
private val descriptionElement = document.getElementById("projectDescriptionInput") as HTMLInputElement
|
||||
private val urlElement = document.getElementById("projectUrlInput") as HTMLInputElement
|
||||
private val vcsUrlElement = document.getElementById("projectVCSUrlInput") as HTMLInputElement
|
||||
private val disableGpgSigningElement = document.getElementById("disableGpgSigning") as HTMLElement
|
||||
private val optionalGpgSigningElement = document.getElementById("optionalGpgSigning") as HTMLElement
|
||||
private val enableGpgSigningElement = document.getElementById("enableGpgSigning") as HTMLElement
|
||||
private val includeMavenCentralElement = document.getElementById("includeMavenCentralTargetRepoToggle") as HTMLInputElement
|
||||
private val developersView = DevelopersView(document.getElementById("developersListDiv") as HTMLElement)
|
||||
private val repositoriesView = RepositoriesView(document.getElementById("repositoriesListDiv") as HTMLElement)
|
||||
|
||||
private var gpgSignMode: GpgSigning = GpgSigning.Disabled
|
||||
set(value) {
|
||||
field = value
|
||||
when (value) {
|
||||
GpgSigning.Enabled -> {
|
||||
enableGpgSigningElement.ukActive = true
|
||||
disableGpgSigningElement.ukActive = false
|
||||
optionalGpgSigningElement.ukActive = false
|
||||
}
|
||||
GpgSigning.Optional -> {
|
||||
enableGpgSigningElement.ukActive = false
|
||||
disableGpgSigningElement.ukActive = false
|
||||
optionalGpgSigningElement.ukActive = true
|
||||
}
|
||||
GpgSigning.Disabled -> {
|
||||
enableGpgSigningElement.ukActive = false
|
||||
disableGpgSigningElement.ukActive = true
|
||||
optionalGpgSigningElement.ukActive = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var mavenConfig: MavenConfig
|
||||
get() = MavenConfig(
|
||||
nameElement.value.ifBlank { defaultProjectName },
|
||||
descriptionElement.value.ifBlank { defaultProjectDescription },
|
||||
urlElement.value,
|
||||
vcsUrlElement.value,
|
||||
developersView.developers,
|
||||
repositoriesView.repositories + if (includeMavenCentralElement.checked) {
|
||||
listOf(SonatypeRepository)
|
||||
} else {
|
||||
emptyList()
|
||||
},
|
||||
when {
|
||||
optionalGpgSigningElement.ukActive -> GpgSigning.Optional
|
||||
enableGpgSigningElement.ukActive -> GpgSigning.Enabled
|
||||
else -> GpgSigning.Disabled
|
||||
}
|
||||
)
|
||||
set(value) {
|
||||
nameElement.value = value.name
|
||||
descriptionElement.value = value.description
|
||||
urlElement.value = value.url
|
||||
vcsUrlElement.value = value.vcsUrl
|
||||
gpgSignMode = if (value.includeGpgSigning) {
|
||||
GpgSigning.Enabled
|
||||
} else {
|
||||
value.gpgSigning
|
||||
}
|
||||
developersView.developers = value.developers
|
||||
val reposWithoutSonatype = value.repositories.filter { it != SonatypeRepository }
|
||||
includeMavenCentralElement.checked = value.repositories.size != reposWithoutSonatype.size
|
||||
repositoriesView.repositories = reposWithoutSonatype
|
||||
}
|
||||
|
||||
init {
|
||||
enableGpgSigningElement.onclick = { gpgSignMode = GpgSigning.Enabled; Unit }
|
||||
disableGpgSigningElement.onclick = { gpgSignMode = GpgSigning.Disabled; Unit }
|
||||
optionalGpgSigningElement.onclick = { gpgSignMode = GpgSigning.Optional; Unit }
|
||||
}
|
||||
}
|
@@ -0,0 +1,41 @@
|
||||
package dev.inmo.kmppscriptbuilder.web.views
|
||||
|
||||
import dev.inmo.kmppscriptbuilder.web.utils.keepScrolling
|
||||
import org.w3c.dom.HTMLElement
|
||||
|
||||
abstract class MutableListView<T>(
|
||||
rootElement: HTMLElement,
|
||||
addButtonText: String = "Add",
|
||||
private val removeButtonText: String = "Remove"
|
||||
) : ListView<T>(rootElement) {
|
||||
init {
|
||||
rootElement.createPrimaryButton(addButtonText).apply {
|
||||
onclick = {
|
||||
keepScrolling {
|
||||
val newObject = createPlainObject()
|
||||
data += newObject
|
||||
}
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract fun createPlainObject(): T
|
||||
protected open fun HTMLElement.addContentBeforeRemoveButton(value: T) {}
|
||||
protected open fun HTMLElement.addContentAfterRemoveButton(value: T) {}
|
||||
final override fun HTMLElement.placeElement(value: T) {
|
||||
addContentBeforeRemoveButton(value)
|
||||
addRemoveButton()
|
||||
addContentAfterRemoveButton(value)
|
||||
}
|
||||
|
||||
private fun HTMLElement.addRemoveButton() {
|
||||
val button = createPrimaryButton(removeButtonText)
|
||||
button.onclick = {
|
||||
elements.indexOf(button.parentElement).takeIf { it > -1 } ?.also {
|
||||
data -= data[it]
|
||||
} ?: rootElement.removeChild(this@addRemoveButton)
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,39 @@
|
||||
package dev.inmo.kmppscriptbuilder.web.views
|
||||
|
||||
import dev.inmo.kmppscriptbuilder.core.models.*
|
||||
import dev.inmo.kmppscriptbuilder.web.utils.ukActive
|
||||
import kotlinx.browser.document
|
||||
import org.w3c.dom.HTMLElement
|
||||
|
||||
class ProjectTypeView : View {
|
||||
private val mppProjectTypeElement = document.getElementById("mppProjectType") as HTMLElement
|
||||
private val jvmProjectTypeElement = document.getElementById("jvmProjectType") as HTMLElement
|
||||
private val jsProjectTypeElement = document.getElementById("jsProjectType") as HTMLElement
|
||||
|
||||
var projectType: ProjectType
|
||||
get() = when {
|
||||
jvmProjectTypeElement.ukActive -> JVMProjectType
|
||||
jsProjectTypeElement.ukActive -> JSProjectType
|
||||
else -> MultiplatformProjectType
|
||||
}
|
||||
set(value) {
|
||||
mppProjectTypeElement.ukActive = value == MultiplatformProjectType
|
||||
jvmProjectTypeElement.ukActive = value == JVMProjectType
|
||||
jsProjectTypeElement.ukActive = value == JSProjectType
|
||||
}
|
||||
|
||||
init {
|
||||
mppProjectTypeElement.onclick = {
|
||||
projectType = MultiplatformProjectType
|
||||
Unit
|
||||
}
|
||||
jvmProjectTypeElement.onclick = {
|
||||
projectType = JVMProjectType
|
||||
Unit
|
||||
}
|
||||
jsProjectTypeElement.onclick = {
|
||||
projectType = JSProjectType
|
||||
Unit
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,31 @@
|
||||
package dev.inmo.kmppscriptbuilder.web.views
|
||||
|
||||
import dev.inmo.kmppscriptbuilder.core.models.MavenPublishingRepository
|
||||
import org.w3c.dom.*
|
||||
|
||||
class RepositoriesView(rootElement: HTMLElement) : MutableListView<MavenPublishingRepository>(rootElement, "Add repository", "Remove repository") {
|
||||
private val HTMLElement.nameElement: HTMLInputElement
|
||||
get() = getElementsByTagName("input")[0] as HTMLInputElement
|
||||
private val HTMLElement.urlElement: HTMLInputElement
|
||||
get() = getElementsByTagName("input")[1] as HTMLInputElement
|
||||
|
||||
var repositories: List<MavenPublishingRepository>
|
||||
get() = elements.map {
|
||||
MavenPublishingRepository(it.nameElement.value, it.urlElement.value)
|
||||
}
|
||||
set(value) {
|
||||
data = value
|
||||
}
|
||||
|
||||
override fun createPlainObject(): MavenPublishingRepository = MavenPublishingRepository("", "")
|
||||
|
||||
override fun HTMLElement.addContentBeforeRemoveButton(value: MavenPublishingRepository) {
|
||||
createTextField("Repository name", "This name will be used to identify repository in grade").value = value.name
|
||||
createTextField("Repository URL", "For example: https://repo.maven.apache.org/maven2/").value = value.url
|
||||
}
|
||||
|
||||
override fun HTMLElement.updateElement(from: MavenPublishingRepository, to: MavenPublishingRepository) {
|
||||
nameElement.value = to.name
|
||||
urlElement.value = to.url
|
||||
}
|
||||
}
|
@@ -0,0 +1,3 @@
|
||||
package dev.inmo.kmppscriptbuilder.web.views
|
||||
|
||||
interface View
|
@@ -0,0 +1,35 @@
|
||||
package dev.inmo.kmppscriptbuilder.web.views
|
||||
|
||||
import kotlinx.dom.appendElement
|
||||
import org.w3c.dom.*
|
||||
|
||||
fun HTMLElement.createTextField(
|
||||
label: String,
|
||||
placeholder: String
|
||||
): HTMLInputElement {
|
||||
return appendElement("div") {
|
||||
classList.add("uk-margin", "uk-width-1-1")
|
||||
}.appendElement("label") {
|
||||
classList.add("uk-form-label")
|
||||
innerHTML = label
|
||||
}.run {
|
||||
val input = appendElement("input") {
|
||||
classList.add("uk-input", "uk-width-expand")
|
||||
setAttribute("type", "text")
|
||||
setAttribute("placeholder", placeholder)
|
||||
} as HTMLInputElement
|
||||
input
|
||||
}
|
||||
}
|
||||
|
||||
fun HTMLElement.createPrimaryButton(text: String): HTMLButtonElement = (appendElement("button") {
|
||||
classList.add("uk-button", "uk-button-primary")
|
||||
} as HTMLButtonElement).apply {
|
||||
innerText = text
|
||||
}
|
||||
|
||||
fun HTMLElement.createCommonButton(text: String): HTMLButtonElement = (appendElement("button") {
|
||||
classList.add("uk-button", "uk-button-default")
|
||||
} as HTMLButtonElement).apply {
|
||||
innerText = text
|
||||
}
|
85
web/src/jsMain/resources/index.html
Normal file
85
web/src/jsMain/resources/index.html
Normal file
@@ -0,0 +1,85 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Kotlin Publication Scripts Builder</title>
|
||||
<!-- UIkit CSS -->
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/uikit@3.6.17/dist/css/uikit.min.css" />
|
||||
</head>
|
||||
<body>
|
||||
<nav class="uk-navbar-container" uk-navbar>
|
||||
<div class="uk-navbar-left">
|
||||
<div class="uk-padding-small uk-text-lead">Kotlin Publication Scripts Builder</div>
|
||||
<div class="uk-padding-small"><a href="https://github.com/InsanusMokrassar/KotlinPublicationScriptsBuilder"><img src="https://img.shields.io/github/stars/InsanusMokrassar/KotlinPublicationScriptsBuilder?label=Github&style=plastic"/></a></div>
|
||||
</div>
|
||||
<div class="uk-navbar-right">
|
||||
<ul class="uk-navbar-nav">
|
||||
<li uk-tooltip="title: Open config" id="openConfig"><a href="#"><span uk-icon="icon: pull"></span></a></li><!--Open file-->
|
||||
<li uk-tooltip="title: Save config" id="saveConfig"><a href="#"><span uk-icon="icon: push"></span></a></li><!--Save file-->
|
||||
<li uk-tooltip="title: Export script" id="exportScript"><a href="#"><span uk-icon="icon: upload"></span></a></li><!--Save file-->
|
||||
</ul>
|
||||
</div>
|
||||
</nav>
|
||||
<form class="uk-padding-small">
|
||||
<fieldset class="uk-fieldset">
|
||||
<legend class="uk-legend">Project type</legend>
|
||||
<div class="uk-padding-small">
|
||||
<ul class="uk-subnav uk-subnav-pill">
|
||||
<li id="mppProjectType" class="uk-active"><a href="#">Multiplatform</a></li>
|
||||
<li id="jvmProjectType"><a href="#">JVM</a></li>
|
||||
<li id="jsProjectType"><a href="#">JS</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<legend class="uk-legend">Licenses</legend>
|
||||
<div id="licensesListDiv" class="uk-padding-small"></div>
|
||||
|
||||
<legend class="uk-legend">Project information</legend>
|
||||
|
||||
<div class="uk-padding-small">
|
||||
<div class="uk-margin uk-width-1-1">
|
||||
<label class="uk-form-label" for="projectNameInput">Public project name</label>
|
||||
<input id="projectNameInput" class="uk-input uk-width-expand" type="text" placeholder="${project.name}">
|
||||
</div>
|
||||
<div class="uk-margin uk-width-1-1">
|
||||
<label class="uk-form-label" for="projectDescriptionInput">Public project description</label>
|
||||
<input id="projectDescriptionInput" class="uk-input uk-width-expand" type="text" placeholder="${project.name}">
|
||||
</div>
|
||||
<div class="uk-margin uk-width-1-1">
|
||||
<label class="uk-form-label" for="projectUrlInput">Public project URL</label>
|
||||
<input id="projectUrlInput" class="uk-input uk-width-expand" type="text" placeholder="Type url to github or other source with readme">
|
||||
</div>
|
||||
<div class="uk-margin uk-width-1-1">
|
||||
<label class="uk-form-label" for="projectVCSUrlInput">Public project VCS URL (with .git)</label>
|
||||
<input id="projectVCSUrlInput" class="uk-input uk-width-expand" type="text" placeholder="Type url to github .git file">
|
||||
</div>
|
||||
|
||||
<div class="uk-margin">
|
||||
<label>GPG Signing</label>
|
||||
|
||||
<div class="uk-padding-small">
|
||||
<ul class="uk-subnav uk-subnav-pill">
|
||||
<li id="disableGpgSigning" class="uk-active" uk-tooltip="title: Signing will not be added"><a href="#">Disabled</a></li>
|
||||
<li id="optionalGpgSigning" uk-tooltip="title: Signing will be added, but disabled in case of absence 'signatory.keyId'"><a href="#">Optional</a></li>
|
||||
<li id="enableGpgSigning" uk-tooltip="title: Signing will be always enabled"><a href="#">Enabled</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="uk-margin">
|
||||
<label><input id="includeMavenCentralTargetRepoToggle" class="uk-checkbox" type="checkbox"> Include publication to MavenCentral</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<legend class="uk-legend">Developers info</legend>
|
||||
<div id="developersListDiv" class="uk-padding-small"></div>
|
||||
|
||||
<legend class="uk-legend">Repositories info</legend>
|
||||
<div id="repositoriesListDiv" class="uk-padding-small"></div>
|
||||
</fieldset>
|
||||
</form>
|
||||
<!-- UIkit JS -->
|
||||
<script src="https://cdn.jsdelivr.net/npm/uikit@3.6.17/dist/js/uikit.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/uikit@3.6.17/dist/js/uikit-icons.min.js"></script>
|
||||
<!-- Internal JS -->
|
||||
<script src="kmppscriptbuilder.web.js"></script>
|
||||
</body>
|
||||
</html>
|
Reference in New Issue
Block a user