Compare commits

...

22 Commits

Author SHA1 Message Date
a360f081f2 fixes 2025-06-29 19:21:38 +06:00
c954e2cf42 small fix 2025-05-25 13:09:18 +06:00
ffe0f3f33b small improvements 2025-05-16 09:18:31 +06:00
abb22519eb update to support central sonatype 2025-05-16 00:48:43 +06:00
87f77543e2 fix of sign script generation 2023-11-05 13:39:52 +06:00
429f2176f2 update kjsuikit 2023-11-02 22:40:23 +06:00
a56b8ae2b5 Update MavenTemplater.kt 2023-11-02 18:32:19 +06:00
4324620932 fix of web publication 2023-11-02 17:43:12 +06:00
265e839dc7 fix of build 2023-11-02 17:40:56 +06:00
2144ca2cca update to support gradle 8.+ 2023-11-02 17:30:42 +06:00
bf21f92c6f update dependencies 2023-07-10 15:00:35 +06:00
41e8d2c540 update dependencies 2023-04-27 16:45:44 +06:00
047f51fd96 hotfix for header authorization 2022-11-16 21:19:01 +06:00
08da50705c more fixes of workflows to the god of workflows fixes 2022-11-16 20:39:28 +06:00
3c216af814 more fixes of workflows to the god of workflows fixes 2022-11-16 20:35:38 +06:00
6b5ab5acba Update commit-release.yml 2022-11-16 20:34:08 +06:00
f723d55d7e update workflows 2022-11-16 18:39:28 +06:00
c0d0b7521e Update commit-release.yml 2022-11-16 18:22:53 +06:00
7536c67589 Merge pull request #6 from InsanusMokrassar/different_credentials_support
Different credentials support
2022-11-16 17:59:41 +06:00
0770772e7d fix of workflows 2022-11-16 17:58:35 +06:00
c6b1289f5a complete 2022-11-16 17:54:16 +06:00
788fe49aa4 almost completed adding of new creds type UI 2022-11-16 16:45:48 +06:00
26 changed files with 429 additions and 127 deletions

View File

@@ -1,17 +0,0 @@
on: [push]
name: Build
jobs:
build-ubuntu:
name: Commit release
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Setup JDK
uses: actions/setup-java@v1
with:
java-version: 11
- name: Build
run: ./gradlew build packageUberJarForCurrentOS

View File

@@ -19,12 +19,12 @@ 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 build packageUberJarForCurrentOS
run: ./gradlew build packageReleaseUberJarForCurrentOS
- name: Publish Web
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./web/build/distributions
publish_dir: ./core/build/dist/js/productionExecutable
publish_branch: site
- name: Create Release
id: create_release
@@ -38,12 +38,12 @@ jobs:
draft: false
prerelease: true
- name: Upload Ubuntu Release Asset
id: upload-ubuntu-release-asset
id: upload-ubuntu-release-asset
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }} # This pulls from the CREATE RELEASE step above, referencing it's ID to get its outputs object, which include a `upload_url`. See this blog post for more info: https://jasonet.co/posts/new-features-of-github-actions/#passing-data-to-future-steps
asset_path: "./desktop/build/compose/jars/kmppscriptbuilder.desktop-linux-x64-${{ env.version }}${{ env.additional_version }}.jar"
upload_url: ${{ steps.create_release.outputs.upload_url }} # This pulls from the CREATE RELEASE step above, referencing it's ID to get its outputs object, which include a `upload_url`. See this blog post for more info: https://jasonet.co/posts/new-features-of-github-actions/#passing-data-to-future-steps
asset_path: "./core/build/compose/jars/kmppscriptbuilder.core-linux-x64-${{ env.version }}${{ env.additional_version }}.jar"
asset_name: KotlinPublicationScriptsBuilder-linux-x64.jar
asset_content_type: application/java-archive

View File

@@ -0,0 +1,50 @@
package dev.inmo.kmppscriptbuilder.core.export
import dev.inmo.kmppscriptbuilder.core.models.MavenConfig
const val generateCentralSonatypeUploadingPartImports = """import java.nio.charset.StandardCharsets
import java.net.http.HttpClient
import java.net.http.HttpRequest
import java.net.http.HttpResponse"""
const val generateCentralSonatypeUploadingPart = """// This script work based on https://ossrh-staging-api.central.sonatype.com/swagger-ui/#/default/manual_upload_repository
// and getting available open repos and just uploading them
if ((project.hasProperty('SONATYPE_USER') || System.getenv('SONATYPE_USER') != null) && (project.hasProperty('SONATYPE_PASSWORD') || System.getenv('SONATYPE_PASSWORD') != null)) {
def taskName = "uploadSonatypePublication"
if (rootProject.tasks.names.contains(taskName) == false) {
rootProject.tasks.register(taskName) {
doLast {
def username = project.hasProperty('SONATYPE_USER') ? project.property('SONATYPE_USER') : System.getenv('SONATYPE_USER')
def password = project.hasProperty('SONATYPE_PASSWORD') ? project.property('SONATYPE_PASSWORD') : System.getenv('SONATYPE_PASSWORD')
def bearer = Base64.getEncoder().encodeToString("${"$"}username:${"$"}password".getBytes(StandardCharsets.UTF_8))
def client = HttpClient.newHttpClient()
def request = HttpRequest.newBuilder()
.uri(URI.create("https://ossrh-staging-api.central.sonatype.com/manual/search/repositories?state=open"))
.GET()
.header("Content-Type", "application/json")
.header("Authorization", "Bearer ${"$"}bearer")
.build()
def response = client.send(request, HttpResponse.BodyHandlers.ofString())
def keys = new ArrayList<String>()
response.body().findAll("\"key\"[\\s]*:[\\s]*\"[^\"]+\"").forEach {
def key = it.find("[^\"]+\"\$").find("[^\"]+")
keys.add(key)
}
keys.forEach {
println("Start uploading ${"$"}it")
def uploadRequest = HttpRequest.newBuilder()
.uri(URI.create("https://ossrh-staging-api.central.sonatype.com/manual/upload/repository/${"$"}it?publishing_type=user_managed"))
.POST(HttpRequest.BodyPublishers.ofString(""))
.header("Content-Type", "application/json")
.header("Authorization", "Bearer ${"$"}bearer")
.build()
def uploadResponse = client.send(uploadRequest, HttpResponse.BodyHandlers.ofString())
if (uploadResponse.statusCode() != 200) {
throw new IllegalStateException("Faced error of uploading for repo with key ${"$"}it. Response: ${"$"}uploadResponse")
}
}
}
}
}
}"""

View File

@@ -8,18 +8,41 @@ fun GpgSigning.generateMavenConfig() = when (this) {
"""
if (project.hasProperty("signing.gnupg.keyName")) {
apply plugin: 'signing'
signing {
useGpgCmd()
sign publishing.publications
}
task signAll {
tasks.withType(Sign).forEach {
dependsOn(it)
}
}
// Workaround to make android sign operations depend on signing tasks
project.getTasks().withType(AbstractPublishToMaven.class).configureEach {
def signingTasks = project.getTasks().withType(Sign.class)
mustRunAfter(signingTasks)
}
// Workaround to make test tasks use sign
project.getTasks().withType(Sign.class).configureEach { signTask ->
def withoutSign = (signTask.name.startsWith("sign") ? signTask.name.minus("sign") : signTask.name)
def pubName = withoutSign.endsWith("Publication") ? withoutSign.substring(0, withoutSign.length() - "Publication".length()) : withoutSign
// These tasks only exist for native targets, hence findByName() to avoid trying to find them for other targets
// Task ':linkDebugTest<platform>' uses this output of task ':sign<platform>Publication' without declaring an explicit or implicit dependency
def debugTestTask = tasks.findByName("linkDebugTest${'$'}pubName")
if (debugTestTask != null) {
signTask.mustRunAfter(debugTestTask)
}
// Task ':compileTestKotlin<platform>' uses this output of task ':sign<platform>Publication' without declaring an explicit or implicit dependency
def testTask = tasks.findByName("compileTestKotlin${'$'}pubName")
if (testTask != null) {
signTask.mustRunAfter(testTask)
}
}
}
"""
GpgSigning.Enabled ->
@@ -37,5 +60,28 @@ task signAll {
dependsOn(it)
}
}
// Workaround to make android sign operations depend on signing tasks
project.getTasks().withType(AbstractPublishToMaven.class).configureEach {
def signingTasks = project.getTasks().withType(Sign.class)
mustRunAfter(signingTasks)
}
// Workaround to make test tasks use sign
project.getTasks().withType(Sign.class).configureEach { signTask ->
def withoutSign = (signTask.name.startsWith("sign") ? signTask.name.minus("sign") : signTask.name)
def pubName = withoutSign.endsWith("Publication") ? withoutSign.substring(0, withoutSign.length() - "Publication".length()) : withoutSign
// These tasks only exist for native targets, hence findByName() to avoid trying to find them for other targets
// Task ':linkDebugTest<platform>' uses this output of task ':sign<platform>Publication' without declaring an explicit or implicit dependency
def debugTestTask = tasks.findByName("linkDebugTest${'$'}pubName")
if (debugTestTask != null) {
signTask.mustRunAfter(debugTestTask)
}
// Task ':compileTestKotlin<platform>' uses this output of task ':sign<platform>Publication' without declaring an explicit or implicit dependency
def testTask = tasks.findByName("compileTestKotlin${'$'}pubName")
if (testTask != null) {
signTask.mustRunAfter(testTask)
}
}
"""
}

View File

@@ -1,19 +1,23 @@
package dev.inmo.kmppscriptbuilder.core.export.js_only
import dev.inmo.kmppscriptbuilder.core.export.generateCentralSonatypeUploadingPart
import dev.inmo.kmppscriptbuilder.core.export.generateCentralSonatypeUploadingPartImports
import dev.inmo.kmppscriptbuilder.core.export.generateMavenConfig
import dev.inmo.kmppscriptbuilder.core.models.*
fun MavenConfig.buildJsOnlyMavenConfig(licenses: List<License>): String = """
${if (includeCentralSonatypeUploadingScript) "$generateCentralSonatypeUploadingPartImports\n" else ""}
apply plugin: 'maven-publish'
${if (includeCentralSonatypeUploadingScript) "$generateCentralSonatypeUploadingPart\n" else ""}
task javadocJar(type: Jar) {
classifier = 'javadoc'
archiveClassifier = 'javadoc'
}
task sourcesJar(type: Jar) {
kotlin.sourceSets.all {
from(kotlin)
}
classifier = 'sources'
archiveClassifier = 'sources'
}
publishing {
@@ -57,11 +61,11 @@ publishing {
""" }}
}
}
repositories {
${repositories.joinToString("\n ") { it.build(" ") }}
}
}
}
repositories {
${repositories.joinToString("\n ") { it.build(" ") }}
}
}
${gpgSigning.generateMavenConfig()}
""".trimIndent()

View File

@@ -1,18 +1,22 @@
package dev.inmo.kmppscriptbuilder.core.export.jvm_only
import dev.inmo.kmppscriptbuilder.core.export.generateCentralSonatypeUploadingPart
import dev.inmo.kmppscriptbuilder.core.export.generateCentralSonatypeUploadingPartImports
import dev.inmo.kmppscriptbuilder.core.export.generateMavenConfig
import dev.inmo.kmppscriptbuilder.core.models.*
fun MavenConfig.buildJvmOnlyMavenConfig(licenses: List<License>): String = """
${if (includeCentralSonatypeUploadingScript) "$generateCentralSonatypeUploadingPartImports\n" else ""}
apply plugin: 'maven-publish'
${if (includeCentralSonatypeUploadingScript) "$generateCentralSonatypeUploadingPart\n" else ""}
task javadocJar(type: Jar) {
from javadoc
classifier = 'javadoc'
archiveClassifier = 'javadoc'
}
task sourcesJar(type: Jar) {
from sourceSets.main.allSource
classifier = 'sources'
archiveClassifier = 'sources'
}
publishing {
@@ -54,11 +58,11 @@ publishing {
""" }}
}
}
repositories {
${repositories.joinToString("\n ") { it.build(" ") }}
}
}
}
repositories {
${repositories.joinToString("\n ") { it.build(" ") }}
}
}
${gpgSigning.generateMavenConfig()}
""".trimIndent()

View File

@@ -1,13 +1,16 @@
package dev.inmo.kmppscriptbuilder.core.export.mpp
import dev.inmo.kmppscriptbuilder.core.export.generateCentralSonatypeUploadingPart
import dev.inmo.kmppscriptbuilder.core.export.generateCentralSonatypeUploadingPartImports
import dev.inmo.kmppscriptbuilder.core.export.generateMavenConfig
import dev.inmo.kmppscriptbuilder.core.models.*
fun MavenConfig.buildMultiplatformMavenConfig(licenses: List<License>): String = """
${if (includeCentralSonatypeUploadingScript) "$generateCentralSonatypeUploadingPartImports\n" else ""}
apply plugin: 'maven-publish'
${if (includeCentralSonatypeUploadingScript) "$generateCentralSonatypeUploadingPart\n" else ""}
task javadocsJar(type: Jar) {
classifier = 'javadoc'
archiveClassifier = 'javadoc'
}
publishing {
@@ -24,28 +27,24 @@ publishing {
url = "$vcsUrl"
}
developers {
${developers.joinToString("\n") { """
developer {
id = "${it.id}"
name = "${it.name}"
email = "${it.eMail}"
}
""" }}
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}"
}
""" }}
licenses {${licenses.joinToString("\n") { """
license {
name = "${it.title}"
url = "${it.url}"
}""" }}
}
}
repositories {
${repositories.joinToString("\n ") { it.build(" ") }}
}
}
repositories {
${repositories.joinToString("\n ") { it.build(" ") }}
}
}
${gpgSigning.generateMavenConfig()}

View File

@@ -26,6 +26,7 @@ data class MavenConfig(
val gpgSigning: GpgSigning = GpgSigning.Disabled,
@Deprecated("Replaced with gpgSigning")
val includeGpgSigning: Boolean = false,
val includeCentralSonatypeUploadingScript: Boolean = false,
)
@Serializable
@@ -33,13 +34,10 @@ data class MavenPublishingRepository(
val name: String,
val url: String,
val credsType: CredentialsType = CredentialsType.UsernameAndPassword(
"${name.uppercase()}_USER",
"${name.uppercase()}_PASSWORD"
CredentialsType.UsernameAndPassword.defaultUsernameProperty(name),
CredentialsType.UsernameAndPassword.defaultPasswordProperty(name),
)
) {
val defaultUsernameProperty = "${name.uppercase()}_USER"
val defaultPasswordProperty = "${name.uppercase()}_PASSWORD"
val defaultHeaderValueProperty = "${name.uppercase()}_TOKEN"
@Serializable
sealed interface CredentialsType {
@@ -53,14 +51,27 @@ data class MavenPublishingRepository(
val usernameProperty: String,
val passwordProperty: String
): CredentialsType {
constructor(baseParameter: String) : this(
defaultUsernameProperty(baseParameter),
defaultPasswordProperty(baseParameter)
)
override fun buildCheckPart(): String = "(project.hasProperty('${usernameProperty}') || System.getenv('${usernameProperty}') != null) && (project.hasProperty('${passwordProperty}') || System.getenv('${passwordProperty}') != null)"
override fun buildCredsPart(): String {
return """
credentials {
username = project.hasProperty('${usernameProperty}') ? project.property('${usernameProperty}') : System.getenv('${usernameProperty}')
password = project.hasProperty('${passwordProperty}') ? project.property('${passwordProperty}') : System.getenv('${passwordProperty}')
}
"""
}"""
}
companion object {
fun defaultUsernameProperty(name: String): String {
return "${name.uppercase()}_USER"
}
fun defaultPasswordProperty(name: String): String {
return "${name.uppercase()}_PASSWORD"
}
}
}
@Serializable
@@ -75,7 +86,16 @@ return """
name = "$headerName"
value = project.hasProperty('${headerValueProperty}') ? project.property('${headerValueProperty}') : System.getenv('${headerValueProperty}')
}
"""
authentication {
header(HttpHeaderAuthentication)
}"""
}
companion object {
fun defaultValueProperty(name: String): String {
return "${name.uppercase()}_TOKEN"
}
}
}
@@ -98,3 +118,4 @@ ${credsType.buildCredsPart()}
}
val SonatypeRepository = MavenPublishingRepository("sonatype", "https://oss.sonatype.org/service/local/staging/deploy/maven2/")
val CentralSonatypeRepository = MavenPublishingRepository("sonatype", "https://ossrh-staging-api.central.sonatype.com/service/local/staging/deploy/maven2/")

View File

@@ -5,7 +5,7 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import dev.inmo.kmppscriptbuilder.core.models.Config
import dev.inmo.kmppscriptbuilder.core.ui.utils.DefaultBox
import dev.inmo.kmppscriptbuilder.core.ui.utils.DefaultContentColumn
import dev.inmo.kmppscriptbuilder.core.ui.utils.DefaultDivider
@Composable
@@ -45,7 +45,7 @@ class BuilderView : View() {
config = it
}
DefaultBox {
DefaultContentColumn {
projectTypeView.build()
DefaultDivider()
licensesView.build()

View File

@@ -7,7 +7,6 @@ import androidx.compose.runtime.setValue
import dev.inmo.kmppscriptbuilder.core.models.Developer
import dev.inmo.kmppscriptbuilder.core.ui.utils.CommonText
import dev.inmo.kmppscriptbuilder.core.ui.utils.CommonTextField
import dev.inmo.kmppscriptbuilder.core.ui.utils.DefaultBox
import dev.inmo.kmppscriptbuilder.core.ui.utils.DefaultSmallVerticalMargin
class DeveloperState(

View File

@@ -1,6 +1,7 @@
package dev.inmo.kmppscriptbuilder.core.ui
import androidx.compose.runtime.*
import dev.inmo.kmppscriptbuilder.core.models.CentralSonatypeRepository
import dev.inmo.kmppscriptbuilder.core.models.GpgSigning
import dev.inmo.kmppscriptbuilder.core.models.MavenConfig
import dev.inmo.kmppscriptbuilder.core.models.SonatypeRepository
@@ -23,22 +24,31 @@ class MavenInfoView : VerticalView("Project information") {
internal var projectVcsUrlProperty by mutableStateOf("")
internal var gpgSignProperty by mutableStateOf<GpgSigning>(GpgSigning.Disabled)
internal var publishToMavenCentralProperty by mutableStateOf(false)
internal var publishToCentralSonatypeProperty by mutableStateOf(false)
internal var includeCentralSonatypeUploadingScriptProperty by mutableStateOf(false)
internal val developersView = DevelopersView()
internal val repositoriesView = RepositoriesView()
var mavenConfig: MavenConfig
get() = MavenConfig(
projectNameProperty.ifBlank { defaultProjectName },
projectDescriptionProperty.ifBlank { defaultProjectDescription },
projectUrlProperty,
projectVcsUrlProperty,
developersView.developers,
repositoriesView.repositories + if (publishToMavenCentralProperty) {
listOf(SonatypeRepository)
name = projectNameProperty.ifBlank { defaultProjectName },
description = projectDescriptionProperty.ifBlank { defaultProjectDescription },
url = projectUrlProperty,
vcsUrl = projectVcsUrlProperty,
developers = developersView.developers,
repositories = repositoriesView.repositories + if (publishToMavenCentralProperty) {
listOf(
if (publishToCentralSonatypeProperty) {
CentralSonatypeRepository
} else {
SonatypeRepository
}
)
} else {
emptyList()
},
gpgSignProperty
gpgSigning = gpgSignProperty,
includeCentralSonatypeUploadingScript = includeCentralSonatypeUploadingScriptProperty
)
set(value) {
projectNameProperty = value.name
@@ -50,9 +60,11 @@ class MavenInfoView : VerticalView("Project information") {
} else {
value.gpgSigning
}
publishToMavenCentralProperty = value.repositories.any { it == SonatypeRepository }
publishToMavenCentralProperty = value.repositories.any { it == SonatypeRepository || it == CentralSonatypeRepository }
developersView.developers = value.developers
repositoriesView.repositories = value.repositories.filter { it != SonatypeRepository }
repositoriesView.repositories = value.repositories.filter { it != SonatypeRepository && it != CentralSonatypeRepository }
publishToCentralSonatypeProperty = value.repositories.any { it == CentralSonatypeRepository }
includeCentralSonatypeUploadingScriptProperty = value.includeCentralSonatypeUploadingScript
}
private val gpgSigningDrawer = GpgSigningOptionDrawerWithView(this)
@@ -100,6 +112,20 @@ class MavenInfoView : VerticalView("Project information") {
publishToMavenCentralProperty,
placeSwitchAtTheStart = true
) { publishToMavenCentralProperty = it }
if (publishToMavenCentralProperty) {
SwitchWithLabel(
"Use Central Sonatype instead of OSSRH (OSSRH has been deprecated)",
publishToCentralSonatypeProperty,
placeSwitchAtTheStart = true
) { publishToCentralSonatypeProperty = it }
if (publishToCentralSonatypeProperty) {
SwitchWithLabel(
"Add 'uploadSonatypePublication' root project task (required for Central Sonatype publishing)",
includeCentralSonatypeUploadingScriptProperty,
placeSwitchAtTheStart = true
) { includeCentralSonatypeUploadingScriptProperty = it }
}
}
developersView.build()
repositoriesView.build()
}

View File

@@ -3,23 +3,32 @@ package dev.inmo.kmppscriptbuilder.core.ui
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import dev.inmo.kmppscriptbuilder.core.models.MavenPublishingRepository
import dev.inmo.kmppscriptbuilder.core.ui.utils.ButtonsPanel
import dev.inmo.kmppscriptbuilder.core.ui.utils.CommonText
import dev.inmo.kmppscriptbuilder.core.ui.utils.CommonTextField
import dev.inmo.kmppscriptbuilder.core.ui.utils.DefaultContentColumn
import dev.inmo.kmppscriptbuilder.core.ui.utils.DefaultSmallVerticalMargin
import dev.inmo.kmppscriptbuilder.core.ui.utils.Drawer
class RepositoryState(
name: String = "",
url: String = ""
url: String = "",
credsType: MavenPublishingRepository.CredentialsType = MavenPublishingRepository.CredentialsType.UsernameAndPassword(name)
) {
var name: String by mutableStateOf(name)
var url: String by mutableStateOf(url)
var credsType by mutableStateOf(credsType)
fun toRepository() = MavenPublishingRepository(name, url)
fun toRepository() = MavenPublishingRepository(name, url, credsType)
}
private fun MavenPublishingRepository.toRepositoryState() = RepositoryState(name, url)
private fun MavenPublishingRepository.toRepositoryState() = RepositoryState(name, url, credsType)
expect class RepositoryCredentialTypeDrawer : Drawer<MavenPublishingRepository.CredentialsType>
expect fun RepositoryCredentialTypeDrawerWithState(repositoryState: RepositoryState): RepositoryCredentialTypeDrawer
class RepositoriesView : ListView<RepositoryState>("Repositories info") {
var repositories: List<MavenPublishingRepository>
@@ -38,17 +47,96 @@ class RepositoriesView : ListView<RepositoryState>("Repositories info") {
@Composable
override fun buildView(item: RepositoryState) {
val credsTypesDrawer = remember {
RepositoryCredentialTypeDrawerWithState(item)
}
CommonText("Repository name")
CommonTextField(
item.name,
"This name will be used to identify repository in gradle"
) { item.name = it }
) {
val previous = item.name
item.name = it
when (val currentCredsType = item.credsType) {
is MavenPublishingRepository.CredentialsType.HttpHeaderCredentials -> {
if (MavenPublishingRepository.CredentialsType.HttpHeaderCredentials.defaultValueProperty(previous) == currentCredsType.headerValueProperty) {
item.credsType = currentCredsType.copy(
headerValueProperty = MavenPublishingRepository.CredentialsType.HttpHeaderCredentials.defaultValueProperty(it)
)
}
}
MavenPublishingRepository.CredentialsType.Nothing -> {}
is MavenPublishingRepository.CredentialsType.UsernameAndPassword -> {
var current: MavenPublishingRepository.CredentialsType.UsernameAndPassword = currentCredsType
if (MavenPublishingRepository.CredentialsType.UsernameAndPassword.defaultUsernameProperty(previous) == currentCredsType.usernameProperty) {
current = current.copy(
usernameProperty = MavenPublishingRepository.CredentialsType.UsernameAndPassword.defaultUsernameProperty(it)
)
}
if (MavenPublishingRepository.CredentialsType.UsernameAndPassword.defaultPasswordProperty(previous) == currentCredsType.passwordProperty) {
current = current.copy(
passwordProperty = MavenPublishingRepository.CredentialsType.UsernameAndPassword.defaultPasswordProperty(it)
)
}
item.credsType = current
}
}
}
DefaultSmallVerticalMargin()
CommonText("Repository url")
CommonTextField(
item.url,
"For example: https://repo.maven.apache.org/maven2/"
) { item.url = it }
ButtonsPanel(
"Credentials type",
MavenPublishingRepository.CredentialsType.Nothing.takeIf { item.credsType != it } ?: item.credsType,
MavenPublishingRepository.CredentialsType.UsernameAndPassword(item.name).takeIf { item.credsType !is MavenPublishingRepository.CredentialsType.UsernameAndPassword } ?: item.credsType,
MavenPublishingRepository.CredentialsType.HttpHeaderCredentials(
"Authorization",
MavenPublishingRepository.CredentialsType.HttpHeaderCredentials.defaultValueProperty(item.name)
).takeIf { item.credsType !is MavenPublishingRepository.CredentialsType.HttpHeaderCredentials } ?: item.credsType,
) {
with(credsTypesDrawer) {
with(it) {
draw()
}
}
}
DefaultContentColumn {
when (val credsType = item.credsType) {
is MavenPublishingRepository.CredentialsType.HttpHeaderCredentials -> {
CommonText("Header name")
CommonTextField(credsType.headerName) {
item.credsType = credsType.copy(headerName = it)
}
DefaultSmallVerticalMargin()
CommonText("Property name")
CommonTextField(credsType.headerValueProperty) {
item.credsType = credsType.copy(headerValueProperty = it)
}
}
MavenPublishingRepository.CredentialsType.Nothing -> {
CommonText("No parameters for absence of credentials")
}
is MavenPublishingRepository.CredentialsType.UsernameAndPassword -> {
CommonText("Username property name")
CommonTextField(credsType.usernameProperty) {
item.credsType = credsType.copy(usernameProperty = it)
}
DefaultSmallVerticalMargin()
CommonText("Password property name")
CommonTextField(credsType.passwordProperty) {
item.credsType = credsType.copy(passwordProperty = it)
}
}
}
}
}
}

View File

@@ -1,13 +1,13 @@
package dev.inmo.kmppscriptbuilder.core.ui
import androidx.compose.runtime.Composable
import dev.inmo.kmppscriptbuilder.core.ui.utils.DefaultBox
import dev.inmo.kmppscriptbuilder.core.ui.utils.DefaultContentColumn
abstract class VerticalView(protected val title: String) : View() {
abstract val content: @Composable () -> Unit
@Composable
override fun build() {
DefaultBox {
DefaultContentColumn {
DrawVertically(title, content)
}
}

View File

@@ -46,4 +46,4 @@ expect fun DefaultDivider()
expect fun DefaultSmallVerticalMargin()
@Composable
expect fun DefaultBox(block: @Composable () -> Unit)
expect fun DefaultContentColumn(block: @Composable () -> Unit)

View File

@@ -5,17 +5,15 @@ import dev.inmo.jsuikit.elements.DefaultButton
import dev.inmo.jsuikit.modifiers.UIKitButton
import dev.inmo.jsuikit.modifiers.UIKitMargin
import dev.inmo.jsuikit.modifiers.UIKitUtility
import dev.inmo.jsuikit.modifiers.builder
import dev.inmo.kmppscriptbuilder.core.ui.utils.DefaultBox
import dev.inmo.kmppscriptbuilder.core.ui.utils.DefaultContentColumn
import dev.inmo.kmppscriptbuilder.core.ui.utils.Drawer
import dev.inmo.kmppscriptbuilder.core.ui.utils.NoTransform
import org.jetbrains.compose.web.dom.Div
actual class ListViewDrawer<T> : Drawer<ListView<T>> {
@Composable
override fun ListView<T>.draw() {
itemsList.forEach { item ->
DefaultBox {
DefaultContentColumn {
buildView(item)
DefaultButton(removeItemText, UIKitButton.Type.Default, UIKitMargin.Small, UIKitUtility.NoTransform, UIKitUtility.Border.Rounded) {
itemsList.remove(item)

View File

@@ -0,0 +1,32 @@
package dev.inmo.kmppscriptbuilder.core.ui
import androidx.compose.runtime.Composable
import dev.inmo.jsuikit.elements.DefaultButton
import dev.inmo.jsuikit.modifiers.UIKitButton
import dev.inmo.jsuikit.modifiers.UIKitMargin
import dev.inmo.jsuikit.modifiers.UIKitUtility
import dev.inmo.kmppscriptbuilder.core.models.MavenPublishingRepository
import dev.inmo.kmppscriptbuilder.core.ui.utils.Drawer
import dev.inmo.kmppscriptbuilder.core.ui.utils.NoTransform
actual class RepositoryCredentialTypeDrawer(
private val state: RepositoryState
) : Drawer<MavenPublishingRepository.CredentialsType> {
@Composable
override fun MavenPublishingRepository.CredentialsType.draw() {
val name = when (this@draw) {
is MavenPublishingRepository.CredentialsType.HttpHeaderCredentials -> "Headers"
MavenPublishingRepository.CredentialsType.Nothing -> "No"
is MavenPublishingRepository.CredentialsType.UsernameAndPassword -> "Username and password"
}
if (state.credsType == this) {
DefaultButton(name, UIKitButton.Type.Primary, UIKitButton.Size.Small, UIKitMargin.Small.Horizontal, UIKitUtility.NoTransform, UIKitUtility.Border.Rounded)
} else {
DefaultButton(name, UIKitButton.Type.Default, UIKitButton.Size.Small, UIKitMargin.Small.Horizontal, UIKitUtility.NoTransform, UIKitUtility.Border.Rounded) {
state.credsType = this
}
}
}
}
actual fun RepositoryCredentialTypeDrawerWithState(repositoryState: RepositoryState): RepositoryCredentialTypeDrawer = RepositoryCredentialTypeDrawer(repositoryState)

View File

@@ -121,7 +121,7 @@ actual fun DefaultSmallVerticalMargin() {
}
@Composable
actual fun DefaultBox(block: @Composable () -> Unit) {
actual fun DefaultContentColumn(block: @Composable () -> Unit) {
Div(attrsBuilder(UIKitMargin.Small.Horizontal, UIKitMargin.Small.Vertical)) {
block()
}

View File

@@ -1,11 +1,18 @@
package dev.inmo.kmppscriptbuilder.core.ui
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.heightIn
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.Button
import androidx.compose.material.Divider
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.onFocusChanged
import androidx.compose.ui.unit.dp
import dev.inmo.kmppscriptbuilder.core.ui.utils.CommonText
import dev.inmo.kmppscriptbuilder.core.ui.utils.CommonTextField
@@ -14,17 +21,29 @@ import dev.inmo.kmppscriptbuilder.core.ui.utils.Drawer
actual object LicensesDrawer : Drawer<LicensesView> {
@Composable
override fun LicensesView.draw() {
if (searchFieldFocused.value) {
Column {
licensesOffersToShow.value.forEach {
Column(Modifier.padding(16.dp, 8.dp, 8.dp, 8.dp)) {
CommonText(it.title) {
itemsList.add(it.toLicenseState())
licenseSearchFilter = ""
}
Divider()
val internalFocusState = remember { mutableStateOf(false) }
if (searchFieldFocused.value || internalFocusState.value) {
}
Column(
Modifier
.let {
if (searchFieldFocused.value) {
it.heightIn(max = 128.dp)
} else {
it.height(0.dp)
}
}
.verticalScroll(rememberScrollState())
) {
licensesOffersToShow.value.forEach {
Column(Modifier.padding(16.dp, 8.dp, 8.dp, 8.dp)) {
CommonText(it.title) {
itemsList.add(it.toLicenseState())
licenseSearchFilter = ""
internalFocusState.value = false
}
Divider()
}
}
}
}

View File

@@ -1,6 +1,5 @@
package dev.inmo.kmppscriptbuilder.core.ui
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding
import androidx.compose.material.Button
import androidx.compose.material.OutlinedButton
@@ -8,14 +7,14 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import dev.inmo.kmppscriptbuilder.core.ui.utils.CommonText
import dev.inmo.kmppscriptbuilder.core.ui.utils.DefaultBox
import dev.inmo.kmppscriptbuilder.core.ui.utils.DefaultContentColumn
import dev.inmo.kmppscriptbuilder.core.ui.utils.Drawer
actual class ListViewDrawer<T> : Drawer<ListView<T>> {
@Composable
override fun ListView<T>.draw() {
itemsList.forEach { item ->
DefaultBox {
DefaultContentColumn {
buildView(item)
OutlinedButton({ itemsList.remove(item) }, Modifier.padding(8.dp)) {
CommonText(removeItemText,)

View File

@@ -0,0 +1,40 @@
package dev.inmo.kmppscriptbuilder.core.ui
import androidx.compose.foundation.layout.padding
import androidx.compose.material.Button
import androidx.compose.material.OutlinedButton
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import dev.inmo.kmppscriptbuilder.core.models.MavenPublishingRepository
import dev.inmo.kmppscriptbuilder.core.ui.utils.Drawer
actual class RepositoryCredentialTypeDrawer(
private val state: RepositoryState
) : Drawer<MavenPublishingRepository.CredentialsType> {
@Composable
override fun MavenPublishingRepository.CredentialsType.draw() {
val name = when (this@draw) {
is MavenPublishingRepository.CredentialsType.HttpHeaderCredentials -> "Headers"
MavenPublishingRepository.CredentialsType.Nothing -> "No"
is MavenPublishingRepository.CredentialsType.UsernameAndPassword -> "Username and password"
}
if (state.credsType == this) {
Button({}, Modifier.padding(8.dp, 0.dp)) {
Text(name)
}
} else {
OutlinedButton(
{
state.credsType = this
},
Modifier.padding(8.dp, 0.dp)
) {
Text(name)
}
}
}
}
actual fun RepositoryCredentialTypeDrawerWithState(repositoryState: RepositoryState): RepositoryCredentialTypeDrawer = RepositoryCredentialTypeDrawer(repositoryState)

View File

@@ -12,6 +12,7 @@ import androidx.compose.material.Divider
import androidx.compose.material.OutlinedTextField
import androidx.compose.material.Switch
import androidx.compose.material.Text
import androidx.compose.material.TextButton
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
@@ -73,7 +74,11 @@ actual fun CommonTextField(
@Composable
actual fun CommonText(text: String, onClick: (() -> Unit)?) {
Text(text, modifier = Modifier.run { onClick ?.let { clickable(onClick = it) } ?: this })
onClick ?.let {
TextButton(it) {
Text(text)
}
} ?: Text(text)
}
@Composable
@@ -87,7 +92,8 @@ actual fun TitleText(text: String) {
actual fun <T> ButtonsPanel(
title: String,
data: Iterable<T>,
itemDrawer: @Composable (T) -> Unit) {
itemDrawer: @Composable (T) -> Unit
) {
Row {
Text(title, Modifier.padding(8.dp))
data.forEach { itemDrawer(it) }
@@ -105,7 +111,7 @@ actual fun DefaultSmallVerticalMargin() {
}
@Composable
actual fun DefaultBox(block: @Composable () -> Unit) {
actual fun DefaultContentColumn(block: @Composable () -> Unit) {
Column(Modifier.padding(8.dp)) {
block()
}

View File

@@ -4,18 +4,6 @@ kotlin.js.generate.externals=true
kotlin.incremental=true
kotlin.incremental.js=true
kotlin_version=1.7.20
kotlin_coroutines_version=1.6.4
kotlin_serialisation_core_version=1.4.1
ktor_version=2.1.3
micro_utils_version=0.14.2
compose_version=1.2.1
# Dokka
dokka_version=1.7.20
# Project data
group=dev.inmo

View File

@@ -1,15 +1,15 @@
[versions]
kt = "1.7.20"
kt-serialization = "1.4.1"
kt-coroutines = "1.6.4"
kt = "1.9.20"
kt-serialization = "1.6.0"
kt-coroutines = "1.7.3"
jb-compose = "1.2.1"
jb-dokka = "1.7.20"
microutils = "0.14.2"
kjsuikit = "0.4.1"
jb-compose = "1.5.10"
jb-dokka = "1.9.10"
microutils = "0.20.11"
kjsuikit = "0.7.3"
ktor = "2.1.3"
ktor = "2.3.5"
gh-release = "2.4.1"

View File

@@ -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-7.5.1-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip

View File

@@ -13,7 +13,7 @@ kotlin {
commonMain {
dependencies {
implementation kotlin('stdlib')
api "org.jetbrains.kotlinx:kotlinx-serialization-json:$kotlin_serialisation_core_version"
api libs.kt.serialization
}
}
commonTest {

View File

@@ -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"
@@ -14,7 +14,7 @@ kotlin {
commonMain {
dependencies {
implementation kotlin('stdlib')
api "org.jetbrains.kotlinx:kotlinx-serialization-json:$kotlin_serialisation_core_version"
api libs.kt.serialization
}
}
commonTest {