diff --git a/.gitignore b/.gitignore index 6d6a56f8..a680191b 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,5 @@ libs out .DS_Store lib/kotlin-* +build +.history diff --git a/build.gradle b/build.gradle new file mode 100644 index 00000000..3f0053cc --- /dev/null +++ b/build.gradle @@ -0,0 +1,58 @@ +allprojects { + group = 'com.beust' + version = '1.1.0' +} + +subprojects { + apply plugin: 'java' + apply plugin: 'maven-publish' + + ext { + bndlib = '3.5.0' + findbugs = '3.0.2' + groovy = '2.4.12' + gson = '2.8.2' + guice = '4.2.2' + inject = '1' + jaxb = '2.3.0' + jcommander = '1.72' + kotlin = '1.2.71' + maven = '3.5.2' + mavenResolver = '1.1.0' + okhttp = '3.9.1' + okio = '1.13.0' + retrofit = '2.3.0' + slf4j = '1.7.3' + spark = '2.6.0' + testng = '6.12' + + junit = '4.12' + junitJupiter = '5.1.0' + junitPlatform = '1.1.0' + } + + repositories { + mavenCentral() + mavenLocal() + jcenter() + maven { + url = 'https://dl.bintray.com/cbeust/maven' + } + + maven { + url = 'https://repo.maven.apache.org/maven2' + } + } + + sourceCompatibility = '1.7' + + task sourcesJar(type: Jar) { + from sourceSets.main.allJava + archiveClassifier = 'sources' + } + + task javadocJar(type: Jar) { + from javadoc + archiveClassifier = 'javadoc' + } +} diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 00000000..5c2d1cf0 Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 00000000..838e6bc8 --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-5.3-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew new file mode 100755 index 00000000..b0d6d0ab --- /dev/null +++ b/gradlew @@ -0,0 +1,188 @@ +#!/usr/bin/env sh + +# +# Copyright 2015 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################################################################## +## +## 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='"-Xmx64m" "-Xms64m"' + +# 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" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 00000000..9991c503 --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,100 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem http://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@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="-Xmx64m" "-Xms64m" + +@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 diff --git a/kobalt/src/Build.kt b/kobalt/src/Build.kt index 37a558f0..0d09844a 100644 --- a/kobalt/src/Build.kt +++ b/kobalt/src/Build.kt @@ -21,7 +21,7 @@ import java.util.zip.ZipEntry import java.util.zip.ZipOutputStream val bs = buildScript { - repos("http://dl.bintray.com/cbeust/maven") + repos("https://dl.bintray.com/cbeust/maven") } object Versions { @@ -30,7 +30,7 @@ object Versions { val okio = "1.13.0" val retrofit = "2.3.0" val gson = "2.8.2" - val guice = "4.1.0" + val guice = "4.2.2" val maven = "3.5.2" val mavenResolver = "1.1.0" val slf4j = "1.7.3" @@ -92,7 +92,7 @@ val kobaltPluginApi = project { version = readVersion() directory = "modules/kobalt-plugin-api" description = "A build system in Kotlin" - url = "http://beust.com/kobalt" + url = "https://beust.com/kobalt" pom = createPom(name, "A build system in Kotlin") @@ -102,7 +102,7 @@ val kobaltPluginApi = project { "com.google.inject:guice:${Versions.guice}", "com.google.inject.extensions:guice-assistedinject:4.1.0", "javax.inject:javax.inject:1", - "com.google.guava:guava:23.3-jre", + "com.google.guava:guava:27.0.1-jre", "org.apache.maven:maven-model:${Versions.maven}", "io.reactivex:rxjava:1.3.3", "com.squareup.okio:okio:${Versions.okio}", @@ -309,13 +309,13 @@ fun taskCopyVersionForWrapper(project: Project) : TaskResult { fun createPom(projectName: String, projectDescription: String) = Model().apply { name = projectName description = projectDescription - url = "http://beust.com/kobalt" + url = "https://beust.com/kobalt" licenses = listOf(License().apply { name = "Apache-2.0" - url = "http://www.apache.org/licenses/LICENSE-2.0" + url = "https://www.apache.org/licenses/LICENSE-2.0" }) scm = Scm().apply { - url = "http://github.com/cbeust/kobalt" + url = "https://github.com/cbeust/kobalt" connection = "https://github.com/cbeust/kobalt.git" developerConnection = "git@github.com:cbeust/kobalt.git" } @@ -323,4 +323,4 @@ fun createPom(projectName: String, projectDescription: String) = Model().apply { name = "Cedric Beust" email = "cedric@beust.com" }) -} \ No newline at end of file +} diff --git a/kobalt/wrapper/kobalt-wrapper.properties b/kobalt/wrapper/kobalt-wrapper.properties index 6d16713e..0ca8045f 100644 --- a/kobalt/wrapper/kobalt-wrapper.properties +++ b/kobalt/wrapper/kobalt-wrapper.properties @@ -1 +1 @@ -kobalt.version=1.0.117 \ No newline at end of file +kobalt.version=1.0.122 \ No newline at end of file diff --git a/modules/kobalt-plugin-api/build.gradle b/modules/kobalt-plugin-api/build.gradle new file mode 100644 index 00000000..56085220 --- /dev/null +++ b/modules/kobalt-plugin-api/build.gradle @@ -0,0 +1,85 @@ +plugins { + id 'org.jetbrains.kotlin.jvm' version '1.2.71' + id 'com.github.johnrengelman.shadow' version '5.0.0' +} + +dependencies { + implementation "biz.aQute.bnd:biz.aQute.bndlib:$bndlib" + implementation "com.google.code.findbugs:jsr305:$findbugs" + implementation "com.sparkjava:spark-core:$spark" + implementation "com.squareup.okhttp3:logging-interceptor:$okhttp" + implementation 'commons-io:commons-io:2.6' + implementation 'io.reactivex:rxjava:1.3.3' + implementation "javax.inject:javax.inject:$inject" + implementation "javax.xml.bind:jaxb-api:$jaxb" + implementation 'org.apache.commons:commons-compress:1.15' + implementation 'org.apache.maven:maven-aether-provider:3.3.9' + implementation "org.apache.maven.resolver:maven-resolver-api:$mavenResolver" + implementation "org.apache.maven.resolver:maven-resolver-connector-basic:$mavenResolver" + implementation "org.apache.maven.resolver:maven-resolver-impl:$mavenResolver" + implementation "org.apache.maven.resolver:maven-resolver-spi:$mavenResolver" + implementation "org.apache.maven.resolver:maven-resolver-transport-file:$mavenResolver" + implementation "org.apache.maven.resolver:maven-resolver-transport-http:$mavenResolver" + implementation "org.apache.maven.resolver:maven-resolver-util:$mavenResolver" + implementation "org.codehaus.groovy:groovy:$groovy" + implementation 'org.eclipse.jgit:org.eclipse.jgit:4.9.0.201710071750-r' + implementation "org.junit.jupiter:junit-jupiter-engine:$junitJupiter" + implementation "org.junit.platform:junit-platform-console:$junitPlatform" + implementation "org.junit.platform:junit-platform-engine:$junitPlatform" + implementation "org.junit.platform:junit-platform-runner:$junitPlatform" + implementation "org.junit.platform:junit-platform-surefire-provider:$junitPlatform" + implementation "org.junit.vintage:junit-vintage-engine:$junitJupiter" + implementation "org.slf4j:slf4j-simple:$slf4j" + implementation "org.testng:testng:$testng" + implementation 'org.testng.testng-remote:testng-remote:1.3.2' + implementation "com.beust:jcommander:$jcommander" + implementation "com.google.code.gson:gson:$gson" + implementation "com.google.inject:guice:$guice" + implementation "com.google.inject.extensions:guice-assistedinject:$guice" + implementation "com.squareup.okio:okio:$okio" + implementation "com.squareup.retrofit2:converter-gson:$retrofit" + implementation "com.squareup.retrofit2:retrofit:$retrofit" + implementation "org.apache.maven:maven-model:$maven" + implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin" +} + +shadowJar { + classifier = null +} + +test { + useTestNG() +} + +publishing { + publications { + shadow(MavenPublication) { publication -> + project.shadow.component(publication) + artifact sourcesJar + artifact javadocJar + + pom { + name = project.name + description = 'A build system in Kotlin' + url = 'https://beust.com/kobalt' + licenses { + license { + name = 'Apache-2.0' + url = 'https://www.apache.org/licenses/LICENSE-2.0' + } + } + developers { + developer { + name = 'Cedric Beust' + email = 'cedric@beust.com' + } + } + scm { + connection = 'scm:https://github.com/cbeust/kobalt.git' + developerConnection = 'scm:git@github.com:cbeust/kobalt.git' + url = 'https://github.com/cbeust/kobalt' + } + } + } + } +} diff --git a/modules/kobalt-plugin-api/pom.xml b/modules/kobalt-plugin-api/pom.xml new file mode 100644 index 00000000..f9026387 --- /dev/null +++ b/modules/kobalt-plugin-api/pom.xml @@ -0,0 +1,279 @@ + + 4.0.0 + + com.beust + kobalt-pom + 1.1.0 + ../.. + + + kobalt-plugin-api + jar + 1.1.0 + + + + org.jetbrains.kotlin + kotlin-stdlib + ${kotlin.version} + + + org.apache.maven + maven-aether-provider + 3.3.9 + + + org.eclipse.aether + impl + + + org.eclipse.aether + spi + + + org.eclipse.aether + util + + + org.eclipse.aether + api + + + + + org.apache.maven.resolver + maven-resolver-api + ${mavenresolver.version} + + + org.apache.maven.resolver + maven-resolver-spi + ${mavenresolver.version} + + + org.apache.maven.resolver + maven-resolver-util + ${mavenresolver.version} + + + org.apache.maven.resolver + maven-resolver-impl + ${mavenresolver.version} + + + org.apache.maven.resolver + maven-resolver-connector-basic + ${mavenresolver.version} + + + org.apache.maven.resolver + maven-resolver-transport-http + ${mavenresolver.version} + + + org.apache.maven.resolver + maven-resolver-transport-file + ${mavenresolver.version} + + + io.reactivex + rxjava + 1.3.3 + + + com.squareup.okio + okio + ${okio.version} + + + javax.inject + javax.inject + 1 + compile + + + com.google.inject + guice + 4.2.2 + + + com.google.inject.extensions + guice-assistedinject + 4.2.2 + + + com.beust + jcommander + 1.72 + + + org.apache.maven + maven-model + 3.5.2 + + + com.google.code.findbugs + jsr305 + 3.0.2 + + + com.google.code.gson + gson + 2.8.2 + + + com.squareup.retrofit2 + retrofit + 2.3.0 + + + com.squareup.retrofit2 + converter-gson + 2.3.0 + + + biz.aQute.bnd + biz.aQute.bndlib + 3.5.0 + + + com.squareup.okhttp3 + logging-interceptor + ${okhttp3.version} + + + com.sparkjava + spark-core + 2.6.0 + + + org.codehaus.groovy + groovy + 2.4.12 + + + org.apache.commons + commons-compress + 1.15 + + + commons-io + commons-io + 2.6 + + + org.junit.platform + junit-platform-surefire-provider + ${junit.version} + + + org.junit.platform + junit-platform-runner + ${junit.version} + + + org.junit.platform + junit-platform-engine + ${junit.version} + + + org.junit.platform + junit-platform-console + ${junit.version} + + + org.junit.jupiter + junit-jupiter-engine + ${junitJupiter.version} + + + org.junit.vintage + junit-vintage-engine + ${junitJupiter.version} + + + org.testng.testng-remote + testng-remote + 1.3.2 + + + org.testng + testng + ${testng.version} + + + org.eclipse.jgit + org.eclipse.jgit + 4.9.0.201710071750-r + + + org.slf4j + slf4j-simple + ${slf4j.version} + + + + javax.xml.bind + jaxb-api + 2.3.0 + + + + + + + org.jetbrains.kotlin + kotlin-maven-plugin + ${kotlin.version} + + + compile + compile + + + ${project.basedir}/src/main/kotlin + + + + + test-compile + test-compile + + + ${project.basedir}/src/test/kotlin + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.5.1 + + + + default-compile + none + + + + default-testCompile + none + + + java-compile + compile + compile + + + java-test-compile + test-compile + testCompile + + + + + + \ No newline at end of file diff --git a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/Constants.kt b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/Constants.kt index 053d0b92..8eb73c84 100644 --- a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/Constants.kt +++ b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/Constants.kt @@ -13,9 +13,9 @@ object Constants { internal val DEFAULT_REPOS = listOf( // "https://maven-central.storage.googleapis.com/", - HostConfig("http://repo1.maven.org/maven2/", "Maven"), + HostConfig("https://repo1.maven.org/maven2/", "Maven"), HostConfig("https://jcenter.bintray.com/", "JCenter") -// "http://repository.jetbrains.com/all/", // <-- contains snapshots +// "https://repository.jetbrains.com/all/", // <-- contains snapshots // snapshots // "https://oss.sonatype.org/content/repositories/snapshots/" diff --git a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/internal/DocUrl.kt b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/internal/DocUrl.kt index 8acab0ab..93010294 100644 --- a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/internal/DocUrl.kt +++ b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/internal/DocUrl.kt @@ -2,7 +2,7 @@ package com.beust.kobalt.internal class DocUrl { companion object { - private const val HOST = "http://beust.com/kobalt/" + private const val HOST = "https://beust.com/kobalt/" private fun url(path: String) = HOST + path val PUBLISH_PLUGIN_URL = url("plug-ins/index.html#publishing") diff --git a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/internal/GenericRunner.kt b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/internal/GenericRunner.kt index e262cf93..995dba53 100644 --- a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/internal/GenericRunner.kt +++ b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/internal/GenericRunner.kt @@ -116,6 +116,7 @@ abstract class GenericTestRunner: ITestRunnerContributor { val testConfig = project.testConfigs.firstOrNull { it.name == configName } + var errorCode = -1 if (testConfig != null) { val args = args(project, context, classpath, testConfig) if (args.size > 0) { @@ -136,12 +137,7 @@ abstract class GenericTestRunner: ITestRunnerContributor { context.logger.log(project.name, 2, "Running tests with classpath size ${classpath.size}") context.logger.log(project.name, 2, "Launching " + allArgs.joinToString(" ")) val process = pb.start() - val errorCode = process.waitFor() - if (errorCode == 0) { - context.logger.log(project.name, 1, "All tests passed") - } else { - context.logger.log(project.name, 1, "Test failures") - } + errorCode = process.waitFor() result = result || errorCode == 0 } else { context.logger.log(project.name, 1, " No tests to run") @@ -152,6 +148,13 @@ abstract class GenericTestRunner: ITestRunnerContributor { } onFinish(project) + + if (errorCode == 0) { + context.logger.log(project.name, 1, "All tests passed") + } else { + context.logger.log(project.name, 1, longMessage!!) + } + return TestResult(result, shortMessage, longMessage) } diff --git a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/internal/KotlinJarFiles.kt b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/internal/KotlinJarFiles.kt index 3f29427a..123e8b76 100644 --- a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/internal/KotlinJarFiles.kt +++ b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/internal/KotlinJarFiles.kt @@ -16,6 +16,5 @@ class KotlinJarFiles @Inject constructor(val dependencyManager: DependencyManage } val stdlib: File get() = getKotlinCompilerJar("stdlib") - val runtime: File get() = getKotlinCompilerJar("runtime") val compiler: File get() = getKotlinCompilerJar("compiler-embeddable") } diff --git a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/internal/TestNgRunner.kt b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/internal/TestNgRunner.kt index 345919c9..f4ee96f8 100644 --- a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/internal/TestNgRunner.kt +++ b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/internal/TestNgRunner.kt @@ -14,11 +14,14 @@ import org.testng.remote.strprotocol.MessageHelper import org.testng.remote.strprotocol.MessageHub import org.testng.remote.strprotocol.TestResultMessage import org.w3c.dom.Attr +import org.w3c.dom.NodeList import org.xml.sax.InputSource import java.io.File import java.io.FileReader import java.io.IOException import javax.xml.parsers.DocumentBuilderFactory +import javax.xml.xpath.XPathConstants +import javax.xml.xpath.XPathFactory class TestNgRunner : GenericTestRunner() { @@ -27,7 +30,10 @@ class TestNgRunner : GenericTestRunner() { override val annotationPackage = "org.testng" override val runnerName = "TestNG" - fun defaultOutput(project: Project) = KFiles.joinDir(project.buildDirectory, "test-output") + private fun defaultOutputWithoutProjectDir(project: Project) + = KFiles.joinDir(project.buildDirectory, "test-output") + private fun defaultOutput(project: Project) + = KFiles.joinDir(project.directory, project.buildDirectory, "test-output") override fun args(project: Project, context: KobaltContext, classpath: List, testConfig: TestConfig) = arrayListOf().apply { @@ -39,7 +45,9 @@ class TestNgRunner : GenericTestRunner() { if (testConfig.testArgs.none { it == "-d" }) { add("-d") - add(defaultOutput(project)) + // Don't include the project directory here since the generic runner will cd to that directory before + // running the tests + add(defaultOutputWithoutProjectDir(project)) } if (testConfig.testArgs.size == 0) { @@ -77,6 +85,15 @@ class TestNgRunner : GenericTestRunner() { var failed = 0 var skipped = 0 var passed = 0 + val xp = XPathFactory.newInstance().newXPath() + val testMethods = xp.compile("/testng-results/suite/test/class/test-method[@status='FAIL']") + .evaluate(doc, XPathConstants.NODESET) + as NodeList + val failedMethods = arrayListOf() + repeat(testMethods.length) { + val tm = testMethods.item(it) + failedMethods.add(tm.attributes.getNamedItem("signature").textContent) + } repeat(root.attributes.length) { val attribute = root.attributes.item(it) if (attribute is Attr) when (attribute.name) { @@ -90,6 +107,7 @@ class TestNgRunner : GenericTestRunner() { shortMessage = "$passed tests" } else if (failed > 0) { shortMessage = "$failed failed" + (if (skipped > 0) ", $skipped skipped" else "") + " tests" + longMessage = "Failed tests:\n " + failedMethods.joinToString("\n ") } } } diff --git a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/maven/aether/KobaltMavenResolver.kt b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/maven/aether/KobaltMavenResolver.kt index f5fcde59..7c8b705f 100644 --- a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/maven/aether/KobaltMavenResolver.kt +++ b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/maven/aether/KobaltMavenResolver.kt @@ -52,7 +52,7 @@ class KobaltMavenResolver @Inject constructor(val settings: KobaltSettings, } fun error(s1: String, s2: String) { throw KobaltException("Found \"$s1\" but not \"$s2\" in local.properties for ${Kurl.KEY}.$host", - docUrl = "http://beust.com/kobalt/documentation/index.html#maven-repos-authenticated") + docUrl = "https://beust.com/kobalt/documentation/index.html#maven-repos-authenticated") } if (! hostInfo.username.isNullOrBlank() && hostInfo.password.isNullOrBlank()) { error("username", "password") diff --git a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/misc/KFiles.kt b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/misc/KFiles.kt index fc030edd..fcf5b86a 100644 --- a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/misc/KFiles.kt +++ b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/misc/KFiles.kt @@ -57,8 +57,11 @@ class KFiles { "kobalt/wrapper/kobalt-$previousVersion.jar") latestInstalledVersion() val result = listOf("", "modules/kobalt-plugin-api", "modules/wrapper").map { - File(homeDir(KFiles.joinDir("kotlin", "kobalt", it, "kobaltBuild", "classes"))) - .absolutePath + File(homeDir(KFiles.joinDir("kotlin", "kobalt", it, "kobaltBuild", "classes"))) //kobalt build dirs + .absolutePath + } + listOf("modules/kobalt", "modules/kobalt-plugin-api", "modules/wrapper").map { + File(homeDir(KFiles.joinDir("kotlin", "kobalt", it, "target", "classes"))) //maven build dirs + .absolutePath } + listOf(previousJar) debug("Couldn't find ${jarFile.absolutePath}, using\n " + result.joinToString(" ")) return result.filter { File(it).exists() } diff --git a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/misc/KobaltWrapperProperties.kt b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/misc/KobaltWrapperProperties.kt index 06d01e7b..a7b5177d 100644 --- a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/misc/KobaltWrapperProperties.kt +++ b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/misc/KobaltWrapperProperties.kt @@ -24,7 +24,7 @@ class KobaltWrapperProperties @Inject constructor() { } private fun defaultUrlFor(version: String) = - "http://beust.com/kobalt/kobalt-$version.zip" + "https://beust.com/kobalt/kobalt-$version.zip" private val file: File get() = File("$WRAPPER_DIR/$KOBALT_WRAPPER_PROPERTIES") diff --git a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/misc/NewRunCommand.kt b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/misc/NewRunCommand.kt index a41f27d0..e105133b 100644 --- a/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/misc/NewRunCommand.kt +++ b/modules/kobalt-plugin-api/src/main/kotlin/com/beust/kobalt/misc/NewRunCommand.kt @@ -79,7 +79,11 @@ open class NewRunCommand(val info: RunCommandInfo) { val process = pb.start() // Run the command and collect the return code and streams - val returnCode = process.waitFor(60, TimeUnit.SECONDS) + val processFinished = process.waitFor(120, TimeUnit.SECONDS) + + if (!processFinished) + kobaltError("process timed out!") + val input = if (process.inputStream.available() > 0) fromStream(process.inputStream) else listOf() @@ -92,10 +96,9 @@ open class NewRunCommand(val info: RunCommandInfo) { // Check to see if the command succeeded val isSuccess = if (info.containsErrors != null) ! info.containsErrors!!(error) - else isSuccess(if (info.ignoreExitValue) true else returnCode, input, error) + else isSuccess(if (info.ignoreExitValue) true else processFinished, input, error) if (isSuccess) { - kobaltLog(3, "success so far") if (!info.useErrorStreamAsErrorIndicator) { info.successCallback(error + input) } else { diff --git a/modules/kobalt/build.gradle b/modules/kobalt/build.gradle new file mode 100644 index 00000000..57e009c7 --- /dev/null +++ b/modules/kobalt/build.gradle @@ -0,0 +1,79 @@ +plugins { + id 'org.jetbrains.kotlin.jvm' version '1.2.71' + id 'com.github.johnrengelman.shadow' version '5.0.0' +} + +dependencies { + implementation project(':wrapper') + implementation project(':kobalt-plugin-api') + implementation "biz.aQute.bnd:biz.aQute.bndlib:$bndlib" + implementation 'com.github.spullara.mustache.java:compiler:0.9.5' + implementation "com.google.code.findbugs:jsr305:$findbugs" + implementation "com.sparkjava:spark-core:$spark" + implementation "com.squareup.okhttp3:logging-interceptor:$okhttp" + implementation 'com.sun.activation:javax.activation:1.2.0' + implementation "com.sun.xml.bind:jaxb-core:$jaxb" + implementation "com.sun.xml.bind:jaxb-impl:$jaxb" + implementation "javax.inject:javax.inject:$inject" + implementation "javax.xml.bind:jaxb-api:$jaxb" + implementation "org.apache.maven.resolver:maven-resolver-spi:$mavenResolver" + implementation "org.codehaus.groovy:groovy:$groovy" + implementation "com.beust:jcommander:$jcommander" + implementation "com.google.code.gson:gson:$gson" + implementation "com.google.inject:guice:$guice" + implementation "com.google.inject.extensions:guice-assistedinject:$guice" + implementation "com.squareup.retrofit2:converter-gson:$retrofit" + implementation "com.squareup.retrofit2:retrofit:$retrofit" + implementation "org.apache.maven:maven-model:$maven" + implementation "org.jetbrains.kotlin:kotlin-compiler-embeddable:$kotlin" + implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin" + testImplementation 'org.assertj:assertj-core:3.8.0' + testImplementation "org.jetbrains.kotlin:kotlin-test:$kotlin" + testImplementation "org.testng:testng:$testng" +} + +sourceSets { + main.kotlin.srcDirs += "${rootProject.projectDir}../../src/main/kotlin" + test.kotlin.srcDirs += "${rootProject.projectDir}../../src/test/kotlin" +} + +shadowJar { + classifier = null +} + +test { + useTestNG() +} + +publishing { + publications { + shadow(MavenPublication) { publication -> + project.shadow.component(publication) + artifact sourcesJar + artifact javadocJar + + pom { + name = project.name + description = 'A build system in Kotlin' + url = 'https://beust.com/kobalt' + licenses { + license { + name = 'Apache-2.0' + url = 'https://www.apache.org/licenses/LICENSE-2.0' + } + } + developers { + developer { + name = 'Cedric Beust' + email = 'cedric@beust.com' + } + } + scm { + connection = 'scm:https://github.com/cbeust/kobalt.git' + developerConnection = 'scm:git@github.com:cbeust/kobalt.git' + url = 'https://github.com/cbeust/kobalt' + } + } + } + } +} diff --git a/modules/kobalt/pom.xml b/modules/kobalt/pom.xml new file mode 100644 index 00000000..44dc799c --- /dev/null +++ b/modules/kobalt/pom.xml @@ -0,0 +1,231 @@ + + 4.0.0 + + com.beust + kobalt-pom + 1.1.0 + ../.. + + + kobalt + jar + 1.1.0 + + + + com.beust + kobalt-plugin-api + 1.1.0 + + + com.beust + wrapper + 1.1.0 + + + org.jetbrains.kotlin + kotlin-compiler-embeddable + ${kotlin.version} + + + org.jetbrains.kotlin + kotlin-stdlib + ${kotlin.version} + + + com.github.spullara.mustache.java + compiler + 0.9.5 + compile + + + javax.inject + javax.inject + 1 + compile + + + com.google.inject + guice + 4.2.2 + + + com.google.inject.extensions + guice-assistedinject + 4.2.2 + + + com.beust + jcommander + 1.72 + + + org.apache.maven + maven-model + 3.5.2 + + + com.google.code.findbugs + jsr305 + 3.0.2 + + + com.google.code.gson + gson + 2.8.2 + + + com.squareup.retrofit2 + retrofit + 2.3.0 + + + com.squareup.retrofit2 + converter-gson + 2.3.0 + + + biz.aQute.bnd + biz.aQute.bndlib + 3.5.0 + + + com.squareup.okhttp3 + logging-interceptor + ${okhttp3.version} + + + com.sparkjava + spark-core + 2.6.0 + + + org.codehaus.groovy + groovy + 2.4.12 + + + org.apache.maven.resolver + maven-resolver-spi + ${mavenresolver.version} + + + + javax.xml.bind + jaxb-api + 2.3.0 + + + com.sun.xml.bind + jaxb-impl + 2.3.0 + + + com.sun.xml.bind + jaxb-core + 2.3.0 + + + com.sun.activation + javax.activation + 1.2.0 + + + + org.assertj + assertj-core + 3.8.0 + test + + + org.jetbrains.kotlin + kotlin-test + ${kotlin.version} + test + + + org.testng + testng + ${testng.version} + test + + + + + + + org.jetbrains.kotlin + kotlin-maven-plugin + ${kotlin.version} + + + compile + compile + + + ${project.basedir}../../src/main/kotlin + + + + + test-compile + test-compile + + + ${project.basedir}../../src/test/kotlin + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.5.1 + + + + default-compile + none + + + + default-testCompile + none + + + java-compile + compile + compile + + + java-test-compile + test-compile + testCompile + + + + + org.apache.maven.plugins + maven-shade-plugin + 3.2.1 + + + + com.beust.kobalt.MainKt + + + + + + package + + shade + + + + + + + \ No newline at end of file diff --git a/modules/wrapper/build.gradle b/modules/wrapper/build.gradle new file mode 100644 index 00000000..c0b5dafe --- /dev/null +++ b/modules/wrapper/build.gradle @@ -0,0 +1,38 @@ +jar { + manifest { + attributes 'Main-Class': 'com.beust.kobalt.wrapper.Main' + } +} + +publishing { + publications { + maven(MavenPublication) { + from(components.java) + artifact sourcesJar + artifact javadocJar + + pom { + name = project.name + description = 'Wrapper for Kobalt' + url = 'https://beust.com/kobalt' + licenses { + license { + name = 'Apache-2.0' + url = 'https://www.apache.org/licenses/LICENSE-2.0' + } + } + developers { + developer { + name = 'Cedric Beust' + email = 'cedric@beust.com' + } + } + scm { + connection = 'scm:https://github.com/cbeust/kobalt.git' + developerConnection = 'scm:git@github.com:cbeust/kobalt.git' + url = 'https://github.com/cbeust/kobalt' + } + } + } + } +} diff --git a/modules/wrapper/pom.xml b/modules/wrapper/pom.xml new file mode 100644 index 00000000..a9dc8796 --- /dev/null +++ b/modules/wrapper/pom.xml @@ -0,0 +1,28 @@ + + 4.0.0 + + com.beust + kobalt-pom + 1.1.0 + ../.. + + + wrapper + jar + 1.1.0 + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.0 + + 1.7 + 1.7 + + + + + \ No newline at end of file diff --git a/modules/wrapper/src/main/java/com/beust/kobalt/wrapper/Main.java b/modules/wrapper/src/main/java/com/beust/kobalt/wrapper/Main.java index 40e21ea5..f31bbc3f 100644 --- a/modules/wrapper/src/main/java/com/beust/kobalt/wrapper/Main.java +++ b/modules/wrapper/src/main/java/com/beust/kobalt/wrapper/Main.java @@ -118,7 +118,7 @@ public class Main { } private static String downloadUrl(String version) { - return "http://beust.com/kobalt/kobalt-" + version + ".zip"; + return "https://beust.com/kobalt/kobalt-" + version + ".zip"; } private void initWrapperFile(String version) throws IOException { diff --git a/pom.xml b/pom.xml new file mode 100644 index 00000000..3a87c7ac --- /dev/null +++ b/pom.xml @@ -0,0 +1,34 @@ + + 4.0.0 + + com.beust + kobalt-pom + pom + 1.1.0 + + + modules/kobalt-plugin-api + modules/wrapper + modules/kobalt + + + + + testng + https://dl.bintray.com/cbeust/maven + + + + + 1.2.71 + 1.13.0 + 3.9.1 + 1.1.0 + 1.1.0 + 5.1.0 + 6.12 + 1.7.3 + + + \ No newline at end of file diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 00000000..c36e45fd --- /dev/null +++ b/settings.gradle @@ -0,0 +1,5 @@ +rootProject.name = 'kobalt-pom' +include(':kobalt-plugin-api', ':wrapper', ':kobalt') +project(':kobalt-plugin-api').projectDir = file('modules/kobalt-plugin-api') +project(':wrapper').projectDir = file('modules/wrapper') +project(':kobalt').projectDir = file('modules/kobalt') diff --git a/src/main/kotlin/com/beust/kobalt/app/kotlin/KotlinTemplateGenerator.kt b/src/main/kotlin/com/beust/kobalt/app/kotlin/KotlinTemplateGenerator.kt index 4c408d48..f10698c4 100644 --- a/src/main/kotlin/com/beust/kobalt/app/kotlin/KotlinTemplateGenerator.kt +++ b/src/main/kotlin/com/beust/kobalt/app/kotlin/KotlinTemplateGenerator.kt @@ -8,8 +8,8 @@ class KotlinTemplateGenerator : LanguageTemplateGenerator() { override val defaultSourceDirectories = hashSetOf("src/main/kotlin") override val defaultTestDirectories = hashSetOf("src/test/kotlin") override val mainDependencies = arrayListOf( - Pom.Dependency("org.jetbrains.kotlin", "kotlin-runtime", null, Constants.KOTLIN_COMPILER_VERSION), - Pom.Dependency("org.jetbrains.kotlin", "kotlin-stdlib", null, Constants.KOTLIN_COMPILER_VERSION)) + Pom.Dependency("org.jetbrains.kotlin", "kotlin-stdlib", null, Constants.KOTLIN_COMPILER_VERSION) + ) override val testDependencies = arrayListOf() override val directive = "project" override val templateName = "kotlin" diff --git a/src/main/kotlin/com/beust/kobalt/plugin/kotlin/KotlinCompiler.kt b/src/main/kotlin/com/beust/kobalt/plugin/kotlin/KotlinCompiler.kt index b1cfda50..c1429910 100644 --- a/src/main/kotlin/com/beust/kobalt/plugin/kotlin/KotlinCompiler.kt +++ b/src/main/kotlin/com/beust/kobalt/plugin/kotlin/KotlinCompiler.kt @@ -74,17 +74,6 @@ class KotlinCompiler @Inject constructor( File(outputDir).parentFile.mkdirs() } val classpath = cp.joinToString(File.pathSeparator) - val allArgs = arrayListOf( - "-d", outputDir, - "-classpath", classpath, - *(info.compilerArgs.toTypedArray()), - *(info.sourceFiles.toTypedArray()) - ) - - // Get rid of annoying and useless warning - if (! info.compilerArgs.contains("-no-stdlib")) { - allArgs.add("-no-stdlib") - } // If the Kotlin compiler version in settings.xml is different from the default, we // need to spawn a Kotlin compiler in a separate process. Otherwise, we can just invoke @@ -113,13 +102,22 @@ class KotlinCompiler @Inject constructor( .filterNotNull() .joinToString(" ") + val infoDir = info.directory + + val outputDir = + if (infoDir != null) { + KFiles.joinDir(infoDir, info.outputDir.path) + } else { + info.outputDir.path + } + val xFlagsArray = xFlagsString.split(" ").toTypedArray() val newArgs = listOf( "-classpath", compilerClasspath, K2JVMCompiler::class.java.name, *info.compilerArgs.toTypedArray(), "-classpath", classpath, - "-d", info.outputDir.absolutePath, + "-d", outputDir, *xFlagsArray, *info.sourceFiles.toTypedArray()) .filter { ! it.isEmpty() } diff --git a/src/main/kotlin/com/beust/kobalt/plugin/kotlin/KotlinPlugin.kt b/src/main/kotlin/com/beust/kobalt/plugin/kotlin/KotlinPlugin.kt index 3c437628..886f3537 100644 --- a/src/main/kotlin/com/beust/kobalt/plugin/kotlin/KotlinPlugin.kt +++ b/src/main/kotlin/com/beust/kobalt/plugin/kotlin/KotlinPlugin.kt @@ -99,9 +99,10 @@ class KotlinPlugin @Inject constructor(val executors: KobaltExecutors, val depen // IClasspathContributor override fun classpathEntriesFor(project: Project?, context: KobaltContext): List = - if (project == null || accept(project)) { + if (project == null || + context.pluginInfo.plugins.any { it is KotlinPlugin && it.settings.kobaltCompilerVersion == null }) { // All Kotlin projects automatically get the Kotlin runtime added to their class path - listOf(kotlinJarFiles.stdlib, kotlinJarFiles.runtime) + listOf(kotlinJarFiles.stdlib) .map { FileDependency(it.absolutePath) } } else { emptyList() diff --git a/src/main/resources/kobalt.properties b/src/main/resources/kobalt.properties index 0d165cd5..0d568d3c 100644 --- a/src/main/resources/kobalt.properties +++ b/src/main/resources/kobalt.properties @@ -1 +1 @@ -kobalt.version=1.0.117 +kobalt.version=1.0.122 diff --git a/src/main/resources/templates/idea/KotlinJavaRuntime.xml b/src/main/resources/templates/idea/KotlinJavaRuntime.xml index c630c0b8..3792609b 100644 --- a/src/main/resources/templates/idea/KotlinJavaRuntime.xml +++ b/src/main/resources/templates/idea/KotlinJavaRuntime.xml @@ -1,12 +1,12 @@ - + - + \ No newline at end of file