mirror of
https://github.com/InsanusMokrassar/KotlinPublicationScriptsBuilder.git
synced 2024-11-22 00:03:57 +00:00
init
remove version ProjectType now is sealed class, all dependencies are updated, different other updates small fixes add opportunity to set auto publishing flag add override option in bintray add override option in bintray upgrade update publishing update url update sources including update jvm script generating add opportunity to work with input files add option to include gpg signing update versions now this builder will fit to window -.- update builder fix of repos fixes update jvm only maven scripts builder remove bintray small update of extension almost rewritten resolve problem with scrolling complete first version with compose replacements fix colors fix in title of app bar add opportunity to configure maven repositories manualy
This commit is contained in:
parent
d3ca46b602
commit
85e04adddc
10
.gitignore
vendored
Normal file
10
.gitignore
vendored
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
.idea
|
||||||
|
out/*
|
||||||
|
*.iml
|
||||||
|
target
|
||||||
|
|
||||||
|
settings.xml
|
||||||
|
|
||||||
|
.gradle/
|
||||||
|
build/
|
||||||
|
out/
|
53
build.gradle
Normal file
53
build.gradle
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
buildscript {
|
||||||
|
repositories {
|
||||||
|
mavenLocal()
|
||||||
|
jcenter()
|
||||||
|
mavenCentral()
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||||
|
classpath "org.jetbrains.kotlin:kotlin-serialization:$kotlin_version"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
plugins {
|
||||||
|
id "org.jetbrains.kotlin.plugin.serialization" version "$kotlin_version"
|
||||||
|
id("org.jetbrains.compose") version "$compose_version"
|
||||||
|
}
|
||||||
|
|
||||||
|
apply plugin: 'kotlin'
|
||||||
|
|
||||||
|
project.group = "com.insanusmokrassar"
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
mavenLocal()
|
||||||
|
jcenter()
|
||||||
|
mavenCentral()
|
||||||
|
maven { url "https://kotlin.bintray.com/kotlinx" }
|
||||||
|
maven { url "https://maven.pkg.jetbrains.space/public/p/compose/dev" }
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
|
||||||
|
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$kotlin_coroutines_version"
|
||||||
|
implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:$kotlin_serialisation_runtime_version"
|
||||||
|
implementation "dev.inmo:micro_utils.coroutines:$micro_utils_version"
|
||||||
|
implementation(compose.desktop.currentOs)
|
||||||
|
|
||||||
|
implementation "io.ktor:ktor-client:$ktor_version"
|
||||||
|
implementation "io.ktor:ktor-client-cio:$ktor_version"
|
||||||
|
}
|
||||||
|
|
||||||
|
compose.desktop {
|
||||||
|
application {
|
||||||
|
mainClass = "com.insanusmokrassar.kmppscriptbuilder.BuilderKt"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
compileKotlin {
|
||||||
|
kotlinOptions {
|
||||||
|
jvmTarget = "11"
|
||||||
|
useIR = true
|
||||||
|
}
|
||||||
|
}
|
10
gradle.properties
Normal file
10
gradle.properties
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
kotlin_version=1.4.30
|
||||||
|
kotlin_coroutines_version=1.4.2
|
||||||
|
kotlin_serialisation_runtime_version=1.1.0
|
||||||
|
#tornadofx_version=1.7.20
|
||||||
|
ktor_version=1.5.1
|
||||||
|
micro_utils_version=0.4.25
|
||||||
|
|
||||||
|
javafxplugin_version=0.0.9
|
||||||
|
|
||||||
|
compose_version=0.3.0
|
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
Binary file not shown.
5
gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
5
gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
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
|
172
gradlew
vendored
Executable file
172
gradlew
vendored
Executable file
@ -0,0 +1,172 @@
|
|||||||
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
|
##############################################################################
|
||||||
|
##
|
||||||
|
## Gradle start up script for UN*X
|
||||||
|
##
|
||||||
|
##############################################################################
|
||||||
|
|
||||||
|
# Attempt to set APP_HOME
|
||||||
|
# Resolve links: $0 may be a link
|
||||||
|
PRG="$0"
|
||||||
|
# Need this for relative symlinks.
|
||||||
|
while [ -h "$PRG" ] ; do
|
||||||
|
ls=`ls -ld "$PRG"`
|
||||||
|
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||||
|
if expr "$link" : '/.*' > /dev/null; then
|
||||||
|
PRG="$link"
|
||||||
|
else
|
||||||
|
PRG=`dirname "$PRG"`"/$link"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
SAVED="`pwd`"
|
||||||
|
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||||
|
APP_HOME="`pwd -P`"
|
||||||
|
cd "$SAVED" >/dev/null
|
||||||
|
|
||||||
|
APP_NAME="Gradle"
|
||||||
|
APP_BASE_NAME=`basename "$0"`
|
||||||
|
|
||||||
|
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
|
DEFAULT_JVM_OPTS=""
|
||||||
|
|
||||||
|
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||||
|
MAX_FD="maximum"
|
||||||
|
|
||||||
|
warn () {
|
||||||
|
echo "$*"
|
||||||
|
}
|
||||||
|
|
||||||
|
die () {
|
||||||
|
echo
|
||||||
|
echo "$*"
|
||||||
|
echo
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# OS specific support (must be 'true' or 'false').
|
||||||
|
cygwin=false
|
||||||
|
msys=false
|
||||||
|
darwin=false
|
||||||
|
nonstop=false
|
||||||
|
case "`uname`" in
|
||||||
|
CYGWIN* )
|
||||||
|
cygwin=true
|
||||||
|
;;
|
||||||
|
Darwin* )
|
||||||
|
darwin=true
|
||||||
|
;;
|
||||||
|
MINGW* )
|
||||||
|
msys=true
|
||||||
|
;;
|
||||||
|
NONSTOP* )
|
||||||
|
nonstop=true
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||||
|
|
||||||
|
# Determine the Java command to use to start the JVM.
|
||||||
|
if [ -n "$JAVA_HOME" ] ; then
|
||||||
|
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||||
|
# IBM's JDK on AIX uses strange locations for the executables
|
||||||
|
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||||
|
else
|
||||||
|
JAVACMD="$JAVA_HOME/bin/java"
|
||||||
|
fi
|
||||||
|
if [ ! -x "$JAVACMD" ] ; then
|
||||||
|
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||||
|
|
||||||
|
Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
location of your Java installation."
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
JAVACMD="java"
|
||||||
|
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||||
|
|
||||||
|
Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
location of your Java installation."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Increase the maximum file descriptors if we can.
|
||||||
|
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
|
||||||
|
MAX_FD_LIMIT=`ulimit -H -n`
|
||||||
|
if [ $? -eq 0 ] ; then
|
||||||
|
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||||
|
MAX_FD="$MAX_FD_LIMIT"
|
||||||
|
fi
|
||||||
|
ulimit -n $MAX_FD
|
||||||
|
if [ $? -ne 0 ] ; then
|
||||||
|
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# For Darwin, add options to specify how the application appears in the dock
|
||||||
|
if $darwin; then
|
||||||
|
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||||
|
fi
|
||||||
|
|
||||||
|
# For Cygwin, switch paths to Windows format before running java
|
||||||
|
if $cygwin ; then
|
||||||
|
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||||
|
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||||
|
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||||
|
|
||||||
|
# We build the pattern for arguments to be converted via cygpath
|
||||||
|
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||||
|
SEP=""
|
||||||
|
for dir in $ROOTDIRSRAW ; do
|
||||||
|
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||||
|
SEP="|"
|
||||||
|
done
|
||||||
|
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||||
|
# Add a user-defined pattern to the cygpath arguments
|
||||||
|
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||||
|
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||||
|
fi
|
||||||
|
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||||
|
i=0
|
||||||
|
for arg in "$@" ; do
|
||||||
|
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||||
|
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||||
|
|
||||||
|
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||||
|
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||||
|
else
|
||||||
|
eval `echo args$i`="\"$arg\""
|
||||||
|
fi
|
||||||
|
i=$((i+1))
|
||||||
|
done
|
||||||
|
case $i in
|
||||||
|
(0) set -- ;;
|
||||||
|
(1) set -- "$args0" ;;
|
||||||
|
(2) set -- "$args0" "$args1" ;;
|
||||||
|
(3) set -- "$args0" "$args1" "$args2" ;;
|
||||||
|
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||||
|
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||||
|
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||||
|
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||||
|
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||||
|
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Escape application args
|
||||||
|
save () {
|
||||||
|
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||||
|
echo " "
|
||||||
|
}
|
||||||
|
APP_ARGS=$(save "$@")
|
||||||
|
|
||||||
|
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
||||||
|
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
||||||
|
|
||||||
|
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
|
||||||
|
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
|
||||||
|
cd "$(dirname "$0")"
|
||||||
|
fi
|
||||||
|
|
||||||
|
exec "$JAVACMD" "$@"
|
84
gradlew.bat
vendored
Normal file
84
gradlew.bat
vendored
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
@if "%DEBUG%" == "" @echo off
|
||||||
|
@rem ##########################################################################
|
||||||
|
@rem
|
||||||
|
@rem Gradle startup script for Windows
|
||||||
|
@rem
|
||||||
|
@rem ##########################################################################
|
||||||
|
|
||||||
|
@rem Set local scope for the variables with windows NT shell
|
||||||
|
if "%OS%"=="Windows_NT" setlocal
|
||||||
|
|
||||||
|
set DIRNAME=%~dp0
|
||||||
|
if "%DIRNAME%" == "" set DIRNAME=.
|
||||||
|
set APP_BASE_NAME=%~n0
|
||||||
|
set APP_HOME=%DIRNAME%
|
||||||
|
|
||||||
|
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
|
set DEFAULT_JVM_OPTS=
|
||||||
|
|
||||||
|
@rem Find java.exe
|
||||||
|
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||||
|
|
||||||
|
set JAVA_EXE=java.exe
|
||||||
|
%JAVA_EXE% -version >NUL 2>&1
|
||||||
|
if "%ERRORLEVEL%" == "0" goto init
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||||
|
echo.
|
||||||
|
echo Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
echo location of your Java installation.
|
||||||
|
|
||||||
|
goto fail
|
||||||
|
|
||||||
|
:findJavaFromJavaHome
|
||||||
|
set JAVA_HOME=%JAVA_HOME:"=%
|
||||||
|
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||||
|
|
||||||
|
if exist "%JAVA_EXE%" goto init
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||||
|
echo.
|
||||||
|
echo Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
echo location of your Java installation.
|
||||||
|
|
||||||
|
goto fail
|
||||||
|
|
||||||
|
:init
|
||||||
|
@rem Get command-line arguments, handling Windows variants
|
||||||
|
|
||||||
|
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||||
|
|
||||||
|
:win9xME_args
|
||||||
|
@rem Slurp the command line arguments.
|
||||||
|
set CMD_LINE_ARGS=
|
||||||
|
set _SKIP=2
|
||||||
|
|
||||||
|
:win9xME_args_slurp
|
||||||
|
if "x%~1" == "x" goto execute
|
||||||
|
|
||||||
|
set CMD_LINE_ARGS=%*
|
||||||
|
|
||||||
|
:execute
|
||||||
|
@rem Setup the command line
|
||||||
|
|
||||||
|
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||||
|
|
||||||
|
@rem Execute Gradle
|
||||||
|
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
||||||
|
|
||||||
|
:end
|
||||||
|
@rem End local scope for the variables with windows NT shell
|
||||||
|
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||||
|
|
||||||
|
:fail
|
||||||
|
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||||
|
rem the _cmd.exe /c_ return code!
|
||||||
|
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||||
|
exit /b 1
|
||||||
|
|
||||||
|
:mainEnd
|
||||||
|
if "%OS%"=="Windows_NT" endlocal
|
||||||
|
|
||||||
|
:omega
|
8
settings.gradle
Normal file
8
settings.gradle
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
pluginManagement {
|
||||||
|
repositories {
|
||||||
|
gradlePluginPortal()
|
||||||
|
maven { url "https://maven.pkg.jetbrains.space/public/p/compose/dev" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rootProject.name = 'KotlinPublicationScriptsBuilder'
|
@ -0,0 +1,62 @@
|
|||||||
|
package com.insanusmokrassar.kmppscriptbuilder
|
||||||
|
|
||||||
|
import androidx.compose.desktop.Window
|
||||||
|
import androidx.compose.foundation.*
|
||||||
|
import androidx.compose.foundation.layout.*
|
||||||
|
import androidx.compose.material.*
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import com.insanusmokrassar.kmppscriptbuilder.utils.*
|
||||||
|
import com.insanusmokrassar.kmppscriptbuilder.views.*
|
||||||
|
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") {
|
||||||
|
val builder = BuilderView()
|
||||||
|
MaterialTheme(
|
||||||
|
Colors(
|
||||||
|
primary = Color(0x01, 0x57, 0x9b),
|
||||||
|
primaryVariant = Color(0x00, 0x2f, 0x6c),
|
||||||
|
secondary = Color(0xb2, 0xeb, 0xf2),
|
||||||
|
secondaryVariant = Color(0x81, 0xb9, 0xbf),
|
||||||
|
background = Color(0xe1, 0xe2, 0xe1),
|
||||||
|
surface = Color(0xf5, 0xf5, 0xf6),
|
||||||
|
error = Color(0xb7, 0x1c, 0x1c),
|
||||||
|
onPrimary = Color.White,
|
||||||
|
onSecondary = Color.Black,
|
||||||
|
onBackground = Color.Black,
|
||||||
|
onSurface = Color.Black,
|
||||||
|
onError = Color.White,
|
||||||
|
isLight = MaterialTheme.colors.isLight,
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
Box(
|
||||||
|
Modifier.fillMaxSize()
|
||||||
|
.background(color = Color(245, 245, 245))
|
||||||
|
) {
|
||||||
|
|
||||||
|
val stateVertical = rememberScrollState(0)
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.verticalScroll(stateVertical)
|
||||||
|
) {
|
||||||
|
builder.init()
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
VerticalScrollbar(
|
||||||
|
modifier = Modifier.align(Alignment.CenterEnd).fillMaxHeight(),
|
||||||
|
adapter = rememberScrollbarAdapter(stateVertical)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (args.isNotEmpty()) {
|
||||||
|
val config = loadConfigFile(File(args.first()))
|
||||||
|
builder.config = config
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,69 @@
|
|||||||
|
package com.insanusmokrassar.kmppscriptbuilder.export.jvm_only
|
||||||
|
|
||||||
|
import com.insanusmokrassar.kmppscriptbuilder.models.*
|
||||||
|
|
||||||
|
fun MavenConfig.buildJvmOnlyMavenConfig(licenses: List<License>): String = """
|
||||||
|
apply plugin: 'maven-publish'
|
||||||
|
${if (includeGpgSigning) "apply plugin: 'signing'\n" else ""}
|
||||||
|
|
||||||
|
task javadocJar(type: Jar) {
|
||||||
|
from javadoc
|
||||||
|
classifier = 'javadoc'
|
||||||
|
}
|
||||||
|
task sourcesJar(type: Jar) {
|
||||||
|
from sourceSets.main.allSource
|
||||||
|
classifier = 'sources'
|
||||||
|
}
|
||||||
|
|
||||||
|
publishing {
|
||||||
|
publications {
|
||||||
|
maven(MavenPublication) {
|
||||||
|
from components.java
|
||||||
|
|
||||||
|
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(" ") }}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
${if (includeGpgSigning) """
|
||||||
|
signing {
|
||||||
|
useGpgCmd()
|
||||||
|
sign publishing.publications
|
||||||
|
}
|
||||||
|
""" else ""}
|
||||||
|
""".trimIndent()
|
@ -0,0 +1,56 @@
|
|||||||
|
package com.insanusmokrassar.kmppscriptbuilder.export.mpp
|
||||||
|
|
||||||
|
import com.insanusmokrassar.kmppscriptbuilder.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'
|
||||||
|
}
|
||||||
|
|
||||||
|
publishing {
|
||||||
|
publications.all {
|
||||||
|
artifact javadocsJar
|
||||||
|
|
||||||
|
pom {
|
||||||
|
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(" ") }}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
${if (includeGpgSigning) """
|
||||||
|
signing {
|
||||||
|
useGpgCmd()
|
||||||
|
sign publishing.publications
|
||||||
|
}
|
||||||
|
""" else ""}
|
||||||
|
""".trimIndent()
|
@ -0,0 +1,13 @@
|
|||||||
|
package com.insanusmokrassar.kmppscriptbuilder.models
|
||||||
|
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class BintrayConfig(
|
||||||
|
val repoUser: String = "\${project.hasProperty('BINTRAY_USER') ? project.property('BINTRAY_USER') : System.getenv('BINTRAY_USER')}",
|
||||||
|
val repo: String,
|
||||||
|
val packageName: String,
|
||||||
|
val packageVcs: String,
|
||||||
|
val autoPublish: Boolean = false,
|
||||||
|
val overridePublish: Boolean = false
|
||||||
|
)
|
@ -0,0 +1,72 @@
|
|||||||
|
package com.insanusmokrassar.kmppscriptbuilder.models
|
||||||
|
|
||||||
|
import com.insanusmokrassar.kmppscriptbuilder.export.jvm_only.buildJvmOnlyMavenConfig
|
||||||
|
import com.insanusmokrassar.kmppscriptbuilder.export.mpp.buildMultiplatformMavenConfig
|
||||||
|
import kotlinx.serialization.*
|
||||||
|
import kotlinx.serialization.builtins.serializer
|
||||||
|
import kotlinx.serialization.descriptors.SerialDescriptor
|
||||||
|
import kotlinx.serialization.encoding.Decoder
|
||||||
|
import kotlinx.serialization.encoding.Encoder
|
||||||
|
|
||||||
|
@Serializable(ProjectTypeSerializer::class)
|
||||||
|
sealed class ProjectType {
|
||||||
|
abstract val name: String
|
||||||
|
// abstract fun buildBintrayGradleConfig(bintrayConfig: BintrayConfig, licenses: List<License>): String
|
||||||
|
abstract fun buildMavenGradleConfig(mavenConfig: MavenConfig, licenses: List<License>): String
|
||||||
|
}
|
||||||
|
|
||||||
|
@Serializer(ProjectType::class)
|
||||||
|
internal object ProjectTypeSerializer : KSerializer<ProjectType> {
|
||||||
|
override val descriptor: SerialDescriptor = String.serializer().descriptor
|
||||||
|
override fun deserialize(decoder: Decoder): ProjectType {
|
||||||
|
return when (decoder.decodeString()) {
|
||||||
|
JVMProjectType.name -> JVMProjectType
|
||||||
|
else -> MultiplatformProjectType
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun serialize(encoder: Encoder, value: ProjectType) {
|
||||||
|
encoder.encodeString(value.name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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,
|
||||||
|
licenses: List<License>
|
||||||
|
): String = mavenConfig.buildMultiplatformMavenConfig(
|
||||||
|
licenses
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
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,
|
||||||
|
licenses: List<License>
|
||||||
|
): String = mavenConfig.buildJvmOnlyMavenConfig(
|
||||||
|
licenses
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class Config(
|
||||||
|
val licenses: List<License>,
|
||||||
|
val mavenConfig: MavenConfig,
|
||||||
|
val type: ProjectType = MultiplatformProjectType
|
||||||
|
)
|
@ -0,0 +1,10 @@
|
|||||||
|
package com.insanusmokrassar.kmppscriptbuilder.models
|
||||||
|
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class Developer(
|
||||||
|
val id: String,
|
||||||
|
val name: String,
|
||||||
|
val eMail: String
|
||||||
|
)
|
@ -0,0 +1,48 @@
|
|||||||
|
package com.insanusmokrassar.kmppscriptbuilder.models
|
||||||
|
|
||||||
|
import com.insanusmokrassar.kmppscriptbuilder.utils.serialFormat
|
||||||
|
import io.ktor.client.HttpClient
|
||||||
|
import io.ktor.client.request.get
|
||||||
|
import io.ktor.client.request.url
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
import kotlinx.serialization.builtins.MapSerializer
|
||||||
|
import kotlinx.serialization.builtins.serializer
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class License(
|
||||||
|
val id: String,
|
||||||
|
val title: String,
|
||||||
|
val url: String? = null
|
||||||
|
)
|
||||||
|
|
||||||
|
private val commonLicensesListDeserializer = MapSerializer(String.serializer(), License.serializer())
|
||||||
|
|
||||||
|
private var licenses: Map<String, License>? = null
|
||||||
|
|
||||||
|
suspend fun HttpClient.getLicenses(): Map<String, License> {
|
||||||
|
val answer = get<String> {
|
||||||
|
url("https://licenses.opendefinition.org/licenses/groups/all.json")
|
||||||
|
}
|
||||||
|
return serialFormat.decodeFromString(commonLicensesListDeserializer, answer).also { gotLicenses ->
|
||||||
|
licenses = gotLicenses
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun HttpClient.searchLicense(name: String): List<License> {
|
||||||
|
val licenses = licenses ?: getLicenses()
|
||||||
|
val lowerCase = name.toLowerCase()
|
||||||
|
val upperCase = name.toUpperCase()
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Map<String, License>.searchLicense(name: String): List<License> {
|
||||||
|
val lowerCase = name.toLowerCase()
|
||||||
|
val upperCase = name.toUpperCase()
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,35 @@
|
|||||||
|
package com.insanusmokrassar.kmppscriptbuilder.models
|
||||||
|
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
@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()
|
||||||
|
)
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class MavenPublishingRepository(
|
||||||
|
val name: String,
|
||||||
|
val url: String
|
||||||
|
) {
|
||||||
|
private val nameCapitalized by lazy {
|
||||||
|
name.toUpperCase()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun build(indent: String) = """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')
|
||||||
|
}
|
||||||
|
}""".replace("\n", "\n$indent")
|
||||||
|
}
|
||||||
|
|
||||||
|
val SonatypeRepository = MavenPublishingRepository("sonatype", "https://oss.sonatype.org/service/local/staging/deploy/maven2/")
|
@ -0,0 +1,75 @@
|
|||||||
|
package com.insanusmokrassar.kmppscriptbuilder.utils
|
||||||
|
|
||||||
|
import com.insanusmokrassar.kmppscriptbuilder.models.Config
|
||||||
|
import java.io.File
|
||||||
|
import javax.swing.JFileChooser
|
||||||
|
|
||||||
|
private const val appExtension = "kpsb"
|
||||||
|
|
||||||
|
private var lastFile: File? = null
|
||||||
|
|
||||||
|
fun loadConfigFile(file: File): Config {
|
||||||
|
lastFile = file
|
||||||
|
return serialFormat.decodeFromString(Config.serializer(), file.readText())
|
||||||
|
}
|
||||||
|
|
||||||
|
fun loadConfig(): Config? {
|
||||||
|
val fc = JFileChooser(lastFile ?.parent)
|
||||||
|
fc.addChoosableFileFilter(FileFilter("Kotlin Publication Scripts Builder", Regex(".*\\.$appExtension")))
|
||||||
|
fc.addChoosableFileFilter(FileFilter("JSON", Regex(".*\\.json")))
|
||||||
|
return when (fc.showOpenDialog(null)) {
|
||||||
|
JFileChooser.APPROVE_OPTION -> {
|
||||||
|
val file = fc.selectedFile
|
||||||
|
lastFile = file
|
||||||
|
return serialFormat.decodeFromString(Config.serializer(), fc.selectedFile.readText())
|
||||||
|
}
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun saveConfig(config: Config): Boolean {
|
||||||
|
return lastFile ?.also {
|
||||||
|
it.writeText(serialFormat.encodeToString(Config.serializer(), config))
|
||||||
|
} != null
|
||||||
|
}
|
||||||
|
|
||||||
|
fun exportGradle(config: Config): Boolean {
|
||||||
|
val fc = JFileChooser(lastFile ?.parent)
|
||||||
|
fc.fileSelectionMode = JFileChooser.DIRECTORIES_ONLY
|
||||||
|
return when (fc.showSaveDialog(null)) {
|
||||||
|
JFileChooser.APPROVE_OPTION -> {
|
||||||
|
val file = fc.selectedFile
|
||||||
|
val mavenConfigContent = config.type.buildMavenGradleConfig(
|
||||||
|
config.mavenConfig,
|
||||||
|
config.licenses
|
||||||
|
)
|
||||||
|
File(file, "publish.gradle").apply {
|
||||||
|
delete()
|
||||||
|
createNewFile()
|
||||||
|
writeText(mavenConfigContent)
|
||||||
|
}
|
||||||
|
true
|
||||||
|
}
|
||||||
|
else -> false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun saveAs(config: Config): Boolean {
|
||||||
|
val fc = JFileChooser(lastFile ?.parent)
|
||||||
|
fc.addChoosableFileFilter(FileFilter("Kotlin Publication Scripts Builder", Regex(".*\\.$appExtension")))
|
||||||
|
fc.addChoosableFileFilter(FileFilter("JSON", Regex(".*\\.json")))
|
||||||
|
return when (fc.showSaveDialog(null)) {
|
||||||
|
JFileChooser.APPROVE_OPTION -> {
|
||||||
|
val file = fc.selectedFile
|
||||||
|
val resultFile = if (file.extension == "") {
|
||||||
|
File(file.parentFile, "${file.name}.$appExtension")
|
||||||
|
} else {
|
||||||
|
file
|
||||||
|
}
|
||||||
|
resultFile.writeText(serialFormat.encodeToString(Config.serializer(), config))
|
||||||
|
lastFile = resultFile
|
||||||
|
true
|
||||||
|
}
|
||||||
|
else -> false
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,16 @@
|
|||||||
|
package com.insanusmokrassar.kmppscriptbuilder.utils
|
||||||
|
|
||||||
|
import java.io.File
|
||||||
|
import javax.swing.filechooser.FileFilter
|
||||||
|
|
||||||
|
fun FileFilter(description: String, fileFilter: (File) -> Boolean) = object : FileFilter() {
|
||||||
|
override fun accept(f: File?): Boolean {
|
||||||
|
return fileFilter(f ?: return false)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getDescription(): String = description
|
||||||
|
}
|
||||||
|
|
||||||
|
fun FileFilter(description: String, nameRegex: Regex) = FileFilter(description) {
|
||||||
|
it.name.matches(nameRegex)
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
package com.insanusmokrassar.kmppscriptbuilder.utils
|
||||||
|
|
||||||
|
import kotlinx.serialization.json.Json
|
||||||
|
|
||||||
|
val serialFormat = Json {
|
||||||
|
ignoreUnknownKeys = true
|
||||||
|
}
|
@ -0,0 +1,60 @@
|
|||||||
|
package com.insanusmokrassar.kmppscriptbuilder.utils
|
||||||
|
|
||||||
|
import androidx.compose.foundation.clickable
|
||||||
|
import androidx.compose.foundation.layout.*
|
||||||
|
import androidx.compose.material.*
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.text.TextStyle
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import androidx.compose.ui.unit.sp
|
||||||
|
|
||||||
|
val commonTextFieldTextStyle = TextStyle(
|
||||||
|
fontSize = 12.sp
|
||||||
|
)
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
inline fun TitleText(text: String) = Text(
|
||||||
|
text, Modifier.padding(0.dp, 8.dp), fontSize = 18.sp
|
||||||
|
)
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
inline fun CommonText(text: String, modifier: Modifier = Modifier) = Text(
|
||||||
|
text, modifier = modifier
|
||||||
|
)
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
inline fun CommonTextField(presetText: String, hint: String, noinline onChange: (String) -> Unit) = OutlinedTextField(
|
||||||
|
presetText,
|
||||||
|
onChange,
|
||||||
|
Modifier.fillMaxWidth(),
|
||||||
|
singleLine = true,
|
||||||
|
label = {
|
||||||
|
CommonText(hint)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
inline fun SwitchWithLabel(
|
||||||
|
label: String,
|
||||||
|
checked: Boolean,
|
||||||
|
placeSwitchAtTheStart: Boolean = false,
|
||||||
|
switchEnabled: Boolean = true,
|
||||||
|
modifier: Modifier = Modifier.padding(0.dp, 8.dp),
|
||||||
|
horizontalArrangement: Arrangement.Horizontal = Arrangement.Start,
|
||||||
|
verticalAlignment: Alignment.Vertical = Alignment.Top,
|
||||||
|
switchModifier: Modifier = Modifier.padding(8.dp, 0.dp),
|
||||||
|
noinline onCheckedChange: (Boolean) -> Unit
|
||||||
|
) = Row(modifier, horizontalArrangement, verticalAlignment) {
|
||||||
|
val switchCreator = @Composable {
|
||||||
|
Switch(checked, onCheckedChange, switchModifier, enabled = switchEnabled)
|
||||||
|
}
|
||||||
|
if (placeSwitchAtTheStart) {
|
||||||
|
switchCreator()
|
||||||
|
}
|
||||||
|
CommonText(label, Modifier.align(Alignment.CenterVertically).clickable { })
|
||||||
|
if (!placeSwitchAtTheStart) {
|
||||||
|
switchCreator()
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,34 @@
|
|||||||
|
package com.insanusmokrassar.kmppscriptbuilder.utils
|
||||||
|
|
||||||
|
import androidx.compose.foundation.layout.*
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
|
||||||
|
abstract class View {
|
||||||
|
protected open val defaultModifier = Modifier.fillMaxWidth().padding(8.dp)
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
abstract fun build()
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class VerticalView(val title: String) : View() {
|
||||||
|
abstract val content: @Composable ColumnScope.() -> Unit
|
||||||
|
@Composable
|
||||||
|
override fun build() {
|
||||||
|
TitleText(title)
|
||||||
|
|
||||||
|
Column(
|
||||||
|
defaultModifier
|
||||||
|
) {
|
||||||
|
content()
|
||||||
|
}
|
||||||
|
|
||||||
|
Spacer(Modifier.fillMaxWidth().height(8.dp))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun <T : View> T.init(): T = apply {
|
||||||
|
build()
|
||||||
|
}
|
@ -0,0 +1,103 @@
|
|||||||
|
package com.insanusmokrassar.kmppscriptbuilder.views
|
||||||
|
|
||||||
|
import androidx.compose.foundation.Image
|
||||||
|
import androidx.compose.foundation.clickable
|
||||||
|
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.unit.dp
|
||||||
|
import com.insanusmokrassar.kmppscriptbuilder.models.Config
|
||||||
|
import com.insanusmokrassar.kmppscriptbuilder.utils.*
|
||||||
|
|
||||||
|
class BuilderView : View() {
|
||||||
|
private val projectTypeView = ProjectTypeView()
|
||||||
|
private val mavenInfoView = MavenInfoView()
|
||||||
|
private val licensesView = LicensesView()
|
||||||
|
private var saveAvailableState by mutableStateOf(false)
|
||||||
|
|
||||||
|
override val defaultModifier: Modifier = Modifier.fillMaxSize()
|
||||||
|
|
||||||
|
var config: Config
|
||||||
|
get() = Config(licensesView.licenses, mavenInfoView.mavenConfig, projectTypeView.projectType)
|
||||||
|
set(value) {
|
||||||
|
licensesView.licenses = value.licenses
|
||||||
|
mavenInfoView.mavenConfig = value.mavenConfig
|
||||||
|
projectTypeView.projectType = value.type
|
||||||
|
saveAvailableState = true
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
override fun build() {
|
||||||
|
Box(Modifier.fillMaxSize()) {
|
||||||
|
Column() {
|
||||||
|
TopAppBar(
|
||||||
|
@Composable {
|
||||||
|
CommonText("Kotlin publication scripts builder", Modifier.clickable { println(config) })
|
||||||
|
},
|
||||||
|
actions = {
|
||||||
|
IconButton(
|
||||||
|
{
|
||||||
|
loadConfig()?.also {
|
||||||
|
config = it
|
||||||
|
}
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
Image(
|
||||||
|
painter = svgResource("images/open_file.svg"),
|
||||||
|
contentDescription = "Open file"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (saveAvailableState) {
|
||||||
|
IconButton(
|
||||||
|
{
|
||||||
|
saveConfig(config)
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
Image(
|
||||||
|
painter = svgResource("images/save_file.svg"),
|
||||||
|
contentDescription = "Save file"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (saveAvailableState) {
|
||||||
|
IconButton(
|
||||||
|
{
|
||||||
|
exportGradle(config)
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
Image(
|
||||||
|
painter = svgResource("images/export_gradle.svg"),
|
||||||
|
contentDescription = "Export Gradle script"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
IconButton(
|
||||||
|
{
|
||||||
|
if (saveAs(config)) {
|
||||||
|
saveAvailableState = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
Image(
|
||||||
|
painter = svgResource("images/save_as.svg"),
|
||||||
|
contentDescription = "Export Gradle script"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
Column(Modifier.padding(8.dp)) {
|
||||||
|
projectTypeView.init()
|
||||||
|
Divider()
|
||||||
|
licensesView.init()
|
||||||
|
Divider()
|
||||||
|
mavenInfoView.init()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,51 @@
|
|||||||
|
package com.insanusmokrassar.kmppscriptbuilder.views
|
||||||
|
|
||||||
|
import androidx.compose.runtime.*
|
||||||
|
import com.insanusmokrassar.kmppscriptbuilder.models.Developer
|
||||||
|
import com.insanusmokrassar.kmppscriptbuilder.utils.*
|
||||||
|
|
||||||
|
class DeveloperState(
|
||||||
|
id: String = "",
|
||||||
|
name: String = "",
|
||||||
|
eMail: String = ""
|
||||||
|
) {
|
||||||
|
var id: String by mutableStateOf(id)
|
||||||
|
var name: String by mutableStateOf(name)
|
||||||
|
var eMail: String by mutableStateOf(eMail)
|
||||||
|
|
||||||
|
fun toDeveloper() = Developer(id, name, eMail)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun Developer.toDeveloperState() = DeveloperState(id, name, eMail)
|
||||||
|
|
||||||
|
class DevelopersView : ListView<DeveloperState>("Developers info") {
|
||||||
|
var developers: List<Developer>
|
||||||
|
get() = itemsList.map { it.toDeveloper() }
|
||||||
|
set(value) {
|
||||||
|
itemsList.clear()
|
||||||
|
itemsList.addAll(
|
||||||
|
value.map { it.toDeveloperState() }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override val addItemText: String = "Add developer"
|
||||||
|
override val removeItemText: String = "Remove developer"
|
||||||
|
|
||||||
|
override fun createItem(): DeveloperState = DeveloperState()
|
||||||
|
@Composable
|
||||||
|
override fun buildView(item: DeveloperState) {
|
||||||
|
CommonTextField(
|
||||||
|
item.id,
|
||||||
|
"Developer username"
|
||||||
|
) { item.id = it }
|
||||||
|
CommonTextField(
|
||||||
|
item.name,
|
||||||
|
"Developer name"
|
||||||
|
) { item.name = it }
|
||||||
|
CommonTextField(
|
||||||
|
item.eMail,
|
||||||
|
"Developer E-Mail"
|
||||||
|
) { item.eMail = it }
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,95 @@
|
|||||||
|
package com.insanusmokrassar.kmppscriptbuilder.views
|
||||||
|
|
||||||
|
import androidx.compose.foundation.clickable
|
||||||
|
import androidx.compose.foundation.layout.*
|
||||||
|
import androidx.compose.material.Button
|
||||||
|
import androidx.compose.material.Divider
|
||||||
|
import androidx.compose.runtime.*
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import com.insanusmokrassar.kmppscriptbuilder.models.License
|
||||||
|
import com.insanusmokrassar.kmppscriptbuilder.models.getLicenses
|
||||||
|
import com.insanusmokrassar.kmppscriptbuilder.utils.*
|
||||||
|
import io.ktor.client.HttpClient
|
||||||
|
import kotlinx.coroutines.*
|
||||||
|
|
||||||
|
private class LicenseState(
|
||||||
|
id: String = "",
|
||||||
|
title: String = "",
|
||||||
|
url: String? = null
|
||||||
|
) {
|
||||||
|
var id: String by mutableStateOf(id)
|
||||||
|
var title: String by mutableStateOf(title)
|
||||||
|
var url: String? by mutableStateOf(url)
|
||||||
|
|
||||||
|
fun toLicense() = License(id, title, url)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun License.toLicenseState() = LicenseState(id, title, url)
|
||||||
|
|
||||||
|
class LicensesView: VerticalView("Licenses") {
|
||||||
|
private var licensesListState = mutableStateListOf<LicenseState>()
|
||||||
|
var licenses: List<License>
|
||||||
|
get() = licensesListState.map { it.toLicense() }
|
||||||
|
set(value) {
|
||||||
|
licensesListState.clear()
|
||||||
|
licensesListState.addAll(value.map { it.toLicenseState() })
|
||||||
|
}
|
||||||
|
private val availableLicensesState = mutableStateListOf<License>()
|
||||||
|
private val licensesOffersToShow = mutableStateListOf<License>()
|
||||||
|
private var licenseSearchFilter by mutableStateOf("")
|
||||||
|
|
||||||
|
init {
|
||||||
|
CoroutineScope(Dispatchers.Default).launch {
|
||||||
|
val client = HttpClient()
|
||||||
|
availableLicensesState.addAll(client.getLicenses().values)
|
||||||
|
client.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override val content: @Composable ColumnScope.() -> Unit = {
|
||||||
|
CommonTextField(licenseSearchFilter, "Search filter") { filterText ->
|
||||||
|
licenseSearchFilter = filterText
|
||||||
|
licensesOffersToShow.clear()
|
||||||
|
if (licenseSearchFilter.isNotEmpty()) {
|
||||||
|
licensesOffersToShow.addAll(
|
||||||
|
availableLicensesState.filter { filterText.all { symbol -> symbol.toLowerCase() in it.title } }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Column {
|
||||||
|
licensesOffersToShow.forEach {
|
||||||
|
Column(Modifier.padding(16.dp, 8.dp, 8.dp, 8.dp)) {
|
||||||
|
CommonText(it.title, Modifier.clickable {
|
||||||
|
licensesListState.add(it.toLicenseState())
|
||||||
|
licenseSearchFilter = ""
|
||||||
|
licensesOffersToShow.clear()
|
||||||
|
})
|
||||||
|
Divider()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Button({ licensesListState.add(LicenseState()) }, Modifier.padding(8.dp)) {
|
||||||
|
CommonText("Add empty license")
|
||||||
|
}
|
||||||
|
licensesListState.forEach { license ->
|
||||||
|
Column(Modifier.padding(8.dp)) {
|
||||||
|
CommonTextField(
|
||||||
|
license.id,
|
||||||
|
"License ID"
|
||||||
|
) { license.id = it }
|
||||||
|
CommonTextField(
|
||||||
|
license.title,
|
||||||
|
"License title"
|
||||||
|
) { license.title = it }
|
||||||
|
CommonTextField(
|
||||||
|
license.url ?: "",
|
||||||
|
"License URL"
|
||||||
|
) { license.url = it }
|
||||||
|
Button({ licensesListState.remove(license) }, Modifier.padding(8.dp)) {
|
||||||
|
CommonText("Remove")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,34 @@
|
|||||||
|
package com.insanusmokrassar.kmppscriptbuilder.views
|
||||||
|
|
||||||
|
import androidx.compose.foundation.layout.*
|
||||||
|
import androidx.compose.material.*
|
||||||
|
import androidx.compose.runtime.*
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import com.insanusmokrassar.kmppscriptbuilder.models.Developer
|
||||||
|
import com.insanusmokrassar.kmppscriptbuilder.utils.*
|
||||||
|
|
||||||
|
abstract class ListView<T>(title: String) : VerticalView(title) {
|
||||||
|
protected val itemsList = mutableStateListOf<T>()
|
||||||
|
|
||||||
|
protected open val addItemText: String = "Add"
|
||||||
|
protected open val removeItemText: String = "Remove"
|
||||||
|
|
||||||
|
protected abstract fun createItem(): T
|
||||||
|
@Composable
|
||||||
|
protected abstract fun buildView(item: T)
|
||||||
|
|
||||||
|
override val content: @Composable ColumnScope.() -> Unit = {
|
||||||
|
Button({ itemsList.add(createItem()) }) {
|
||||||
|
CommonText(addItemText)
|
||||||
|
}
|
||||||
|
itemsList.forEach { item ->
|
||||||
|
Column(Modifier.padding(8.dp)) {
|
||||||
|
buildView(item)
|
||||||
|
Button({ itemsList.remove(item) }, Modifier.padding(8.dp)) {
|
||||||
|
CommonText(removeItemText)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,77 @@
|
|||||||
|
package com.insanusmokrassar.kmppscriptbuilder.views
|
||||||
|
|
||||||
|
import androidx.compose.foundation.layout.ColumnScope
|
||||||
|
import androidx.compose.runtime.*
|
||||||
|
import com.insanusmokrassar.kmppscriptbuilder.models.MavenConfig
|
||||||
|
import com.insanusmokrassar.kmppscriptbuilder.models.SonatypeRepository
|
||||||
|
import com.insanusmokrassar.kmppscriptbuilder.utils.*
|
||||||
|
|
||||||
|
class MavenInfoView : VerticalView("Project information") {
|
||||||
|
private var projectNameProperty by mutableStateOf("")
|
||||||
|
private var projectDescriptionProperty by mutableStateOf("")
|
||||||
|
private var projectUrlProperty by mutableStateOf("")
|
||||||
|
private var projectVcsUrlProperty by mutableStateOf("")
|
||||||
|
private var includeGpgSignProperty by mutableStateOf(true)
|
||||||
|
private var publishToMavenCentralProperty by mutableStateOf(false)
|
||||||
|
private val developersView = DevelopersView()
|
||||||
|
private val repositoriesView = RepositoriesView()
|
||||||
|
|
||||||
|
var mavenConfig: MavenConfig
|
||||||
|
get() = MavenConfig(
|
||||||
|
projectNameProperty,
|
||||||
|
projectDescriptionProperty,
|
||||||
|
projectUrlProperty,
|
||||||
|
projectVcsUrlProperty,
|
||||||
|
includeGpgSignProperty,
|
||||||
|
developersView.developers,
|
||||||
|
repositoriesView.repositories + if (publishToMavenCentralProperty) {
|
||||||
|
listOf(SonatypeRepository)
|
||||||
|
} else {
|
||||||
|
emptyList()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
set(value) {
|
||||||
|
projectNameProperty = value.name
|
||||||
|
projectDescriptionProperty = value.description
|
||||||
|
projectUrlProperty = value.url
|
||||||
|
projectVcsUrlProperty = value.vcsUrl
|
||||||
|
includeGpgSignProperty = value.includeGpgSigning
|
||||||
|
publishToMavenCentralProperty = value.repositories.any { it == SonatypeRepository }
|
||||||
|
developersView.developers = value.developers
|
||||||
|
repositoriesView.repositories = value.repositories.filter { it != SonatypeRepository }
|
||||||
|
// developersView.developers = value.developers
|
||||||
|
}
|
||||||
|
|
||||||
|
override val content: @Composable ColumnScope.() -> Unit = {
|
||||||
|
CommonTextField(
|
||||||
|
projectNameProperty,
|
||||||
|
"Public project name"
|
||||||
|
) { projectNameProperty = it }
|
||||||
|
CommonTextField(
|
||||||
|
projectDescriptionProperty,
|
||||||
|
"Public project description"
|
||||||
|
) { projectDescriptionProperty = it }
|
||||||
|
CommonTextField(
|
||||||
|
projectUrlProperty,
|
||||||
|
"Public project URL"
|
||||||
|
) { projectUrlProperty = it }
|
||||||
|
CommonTextField(
|
||||||
|
projectVcsUrlProperty,
|
||||||
|
"Public project VCS URL (with .git)"
|
||||||
|
) { projectVcsUrlProperty = it }
|
||||||
|
|
||||||
|
SwitchWithLabel(
|
||||||
|
"Include GPG Signing",
|
||||||
|
includeGpgSignProperty,
|
||||||
|
placeSwitchAtTheStart = true
|
||||||
|
) { includeGpgSignProperty = it }
|
||||||
|
|
||||||
|
SwitchWithLabel(
|
||||||
|
"Include publication to MavenCentral",
|
||||||
|
publishToMavenCentralProperty,
|
||||||
|
placeSwitchAtTheStart = true
|
||||||
|
) { publishToMavenCentralProperty = it }
|
||||||
|
developersView.init()
|
||||||
|
repositoriesView.init()
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,33 @@
|
|||||||
|
package com.insanusmokrassar.kmppscriptbuilder.views
|
||||||
|
|
||||||
|
import androidx.compose.foundation.layout.*
|
||||||
|
import androidx.compose.material.Switch
|
||||||
|
import androidx.compose.material.Text
|
||||||
|
import androidx.compose.runtime.*
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import com.insanusmokrassar.kmppscriptbuilder.models.*
|
||||||
|
import com.insanusmokrassar.kmppscriptbuilder.utils.VerticalView
|
||||||
|
|
||||||
|
class ProjectTypeView : VerticalView("Project type") {
|
||||||
|
private var projectTypeState by mutableStateOf<Boolean>(false)
|
||||||
|
private val calculatedProjectType: ProjectType
|
||||||
|
get() = if (projectTypeState) JVMProjectType else MultiplatformProjectType
|
||||||
|
var projectType: ProjectType
|
||||||
|
get() = calculatedProjectType
|
||||||
|
set(value) {
|
||||||
|
projectTypeState = value == JVMProjectType
|
||||||
|
}
|
||||||
|
|
||||||
|
override val content: @Composable ColumnScope.() -> Unit = {
|
||||||
|
Row(horizontalArrangement = Arrangement.spacedBy(5.dp)) {
|
||||||
|
Text("Multiplatform", Modifier.alignByBaseline())
|
||||||
|
Switch(
|
||||||
|
projectTypeState,
|
||||||
|
{ projectTypeState = it },
|
||||||
|
Modifier.padding(4.dp, 0.dp)
|
||||||
|
)
|
||||||
|
Text("JVM", Modifier.alignByBaseline())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,45 @@
|
|||||||
|
package com.insanusmokrassar.kmppscriptbuilder.views
|
||||||
|
|
||||||
|
import androidx.compose.runtime.*
|
||||||
|
import com.insanusmokrassar.kmppscriptbuilder.models.MavenPublishingRepository
|
||||||
|
import com.insanusmokrassar.kmppscriptbuilder.utils.*
|
||||||
|
|
||||||
|
class RepositoryState(
|
||||||
|
name: String = "",
|
||||||
|
url: String = ""
|
||||||
|
) {
|
||||||
|
var name: String by mutableStateOf(name)
|
||||||
|
var url: String by mutableStateOf(url)
|
||||||
|
|
||||||
|
fun toRepository() = MavenPublishingRepository(name, url)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun MavenPublishingRepository.toRepositoryState() = RepositoryState(name, url)
|
||||||
|
|
||||||
|
class RepositoriesView : ListView<RepositoryState>("Repositories info") {
|
||||||
|
var repositories: List<MavenPublishingRepository>
|
||||||
|
get() = itemsList.map { it.toRepository() }
|
||||||
|
set(value) {
|
||||||
|
itemsList.clear()
|
||||||
|
itemsList.addAll(
|
||||||
|
value.map { it.toRepositoryState() }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override val addItemText: String = "Add repository"
|
||||||
|
override val removeItemText: String = "Remove repository"
|
||||||
|
|
||||||
|
override fun createItem(): RepositoryState = RepositoryState()
|
||||||
|
@Composable
|
||||||
|
override fun buildView(item: RepositoryState) {
|
||||||
|
CommonTextField(
|
||||||
|
item.name,
|
||||||
|
"Repository name"
|
||||||
|
) { item.name = it }
|
||||||
|
CommonTextField(
|
||||||
|
item.url,
|
||||||
|
"Repository url"
|
||||||
|
) { item.url = it }
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
1
src/main/resources/images/export_gradle.svg
Normal file
1
src/main/resources/images/export_gradle.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="24" height="24" viewBox="0 0 24 24"><path fill="white" d="M14 2H6C4.9 2 4 2.9 4 4V20C4 21.1 4.9 22 6 22H18C19.1 22 20 21.1 20 20V8L14 2M18 20H6V4H13V9H18V20M16 11V18.1L13.9 16L11.1 18.8L8.3 16L11.1 13.2L8.9 11H16Z" /></svg>
|
After Width: | Height: | Size: 463 B |
1
src/main/resources/images/open_file.svg
Normal file
1
src/main/resources/images/open_file.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="24" height="24" viewBox="0 0 24 24"><path fill="white" d="M6.1,10L4,18V8H21A2,2 0 0,0 19,6H12L10,4H4A2,2 0 0,0 2,6V18A2,2 0 0,0 4,20H19C19.9,20 20.7,19.4 20.9,18.5L23.2,10H6.1M19,18H6L7.6,12H20.6L19,18Z" /></svg>
|
After Width: | Height: | Size: 452 B |
1
src/main/resources/images/save_as.svg
Normal file
1
src/main/resources/images/save_as.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="24" height="24" viewBox="0 0 24 24"><path fill="white" d="M4 19H10V21H4C2.89 21 2 20.1 2 19V5C2 3.9 2.89 3 4 3H16L20 7V9.12L18 11.12V7.83L15.17 5H4V19M14 10V6H5V10H14M20.42 12.3C20.31 12.19 20.18 12.13 20.04 12.13C19.9 12.13 19.76 12.19 19.65 12.3L18.65 13.3L20.7 15.35L21.7 14.35C21.92 14.14 21.92 13.79 21.7 13.58L20.42 12.3M12 19.94V22H14.06L20.12 15.93L18.07 13.88L12 19.94M14 15C14 13.34 12.66 12 11 12S8 13.34 8 15 9.34 18 11 18C11.04 18 11.08 18 11.13 18L14 15.13C14 15.09 14 15.05 14 15" /></svg>
|
After Width: | Height: | Size: 744 B |
1
src/main/resources/images/save_file.svg
Normal file
1
src/main/resources/images/save_file.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="24" height="24" viewBox="0 0 24 24"><path fill="white" d="M17 3H5C3.89 3 3 3.9 3 5V19C3 20.1 3.89 21 5 21H19C20.1 21 21 20.1 21 19V7L17 3M19 19H5V5H16.17L19 7.83V19M12 12C10.34 12 9 13.34 9 15S10.34 18 12 18 15 16.66 15 15 13.66 12 12 12M6 6H15V10H6V6Z" /></svg>
|
After Width: | Height: | Size: 502 B |
Loading…
Reference in New Issue
Block a user