You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@buildr.apache.org by to...@apache.org on 2017/07/28 06:39:27 UTC
buildr git commit: Adding support to compiling Kotlin.
Repository: buildr
Updated Branches:
refs/heads/master a55253387 -> 509fb9a42
Adding support to compiling Kotlin.
Project: http://git-wip-us.apache.org/repos/asf/buildr/repo
Commit: http://git-wip-us.apache.org/repos/asf/buildr/commit/509fb9a4
Tree: http://git-wip-us.apache.org/repos/asf/buildr/tree/509fb9a4
Diff: http://git-wip-us.apache.org/repos/asf/buildr/diff/509fb9a4
Branch: refs/heads/master
Commit: 509fb9a42a124d3279a860d10fd5f83369a8990f
Parents: a552533
Author: Antoine Toulme <an...@lunar-ocean.com>
Authored: Sun Jul 23 23:22:14 2017 -0700
Committer: Antoine Toulme <an...@lunar-ocean.com>
Committed: Tue Jul 25 21:22:02 2017 -0700
----------------------------------------------------------------------
.gitignore | 1 +
CHANGELOG | 1 +
buildr.buildfile | 5 +
doc/languages.textile | 24 +-
lib/buildr/kotlin.rb | 17 ++
lib/buildr/kotlin/compiler.rb | 282 +++++++++++++++++++
.../buildr/KotlinMessageCollector$1.class | Bin 0 -> 852 bytes
.../apache/buildr/KotlinMessageCollector.class | Bin 0 -> 1591 bytes
.../apache/buildr/KotlinMessageCollector.java | 46 +++
spec/kotlin/compiler_spec.rb | 274 ++++++++++++++++++
spec/sandbox.rb | 1 +
11 files changed, 650 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/buildr/blob/509fb9a4/.gitignore
----------------------------------------------------------------------
diff --git a/.gitignore b/.gitignore
index 614513b..63a162d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -27,3 +27,4 @@
/site
/lib/buildr/scala/org/apache/buildr/Specs2Runner.class
.bundle
+.DS_Store
http://git-wip-us.apache.org/repos/asf/buildr/blob/509fb9a4/CHANGELOG
----------------------------------------------------------------------
diff --git a/CHANGELOG b/CHANGELOG
index dabc42e..ad3906c 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,4 +1,5 @@
1.5.4 (Pending)
+* Added: Support to compiling Kotlin
1.5.3 (2017-05-17)
* Change: Add support for gwt 2.8.1 to gwt addon.
http://git-wip-us.apache.org/repos/asf/buildr/blob/509fb9a4/buildr.buildfile
----------------------------------------------------------------------
diff --git a/buildr.buildfile b/buildr.buildfile
index f1c9a6a..3d34d2d 100644
--- a/buildr.buildfile
+++ b/buildr.buildfile
@@ -17,6 +17,7 @@ $LOADED_FEATURES << 'jruby' unless RUBY_PLATFORM =~ /java/ # Pretend to have JRu
require 'buildr/jetty'
require 'buildr/nailgun'
require 'buildr/scala'
+require 'buildr/kotlin'
repositories.remote << 'http://repo1.maven.org/maven2'
repositories.remote << 'https://oss.sonatype.org/content/groups/scala-tools'
@@ -31,6 +32,10 @@ define 'buildr' do
define 'scala' do
compile.using(:javac).from(FileList['lib/buildr/scala/**/*.java']).into('lib/buildr/scala')
end
+
+ define 'kotlin' do
+ compile.using(:javac).from(FileList['lib/buildr/kotlin/**/*.java']).into('lib/buildr/kotlin').with(Buildr::Kotlin::Kotlinc.dependencies)
+ end
desc 'Buildr extra packages (Antlr, Cobertura, Hibernate, Javacc, JDepend, Jetty, OpenJPA, XmlBeans)'
define 'extra', :version=>'1.0' do
http://git-wip-us.apache.org/repos/asf/buildr/blob/509fb9a4/doc/languages.textile
----------------------------------------------------------------------
diff --git a/doc/languages.textile b/doc/languages.textile
index 09252e2..3b2cfaf 100644
--- a/doc/languages.textile
+++ b/doc/languages.textile
@@ -490,6 +490,29 @@ end
The @doc@ task is *not* joint-compilation aware. Thus, it will only generate ScalaDoc for mixed-source projects, it will not attempt to generate both JavaDoc and ScalaDoc.
+h2(#kotlin). Kotlin
+
+h3. Compiling Kotlin
+
+To start using Kotlin, you must first require it on your Buildfile:
+
+{% highlight ruby %}
+require 'buildr/kotlin'
+{% endhighlight %}
+
+Any project with a .kt file under the @src/main/kotlin@ directory (by default), compiling them into @target/classes@.
+
+If the project has any java files, they will be compiled using javac.
+
+|_. Option |_. Usage |
+| @verbose@ | Asks the compiler for verbose output, true when running in verbose mode. |
+| @fork@ | Whether to execute groovyc using a spawned instance of the JVM. Defaults to no. |
+| @warnings@ | Issue warnings when compiling. True when running in verbose mode. |
+| @debug@ | Generates bytecode with debugging information. Set from the debug environment variable/global option. |
+| @optimize@ | Generates faster bytecode by applying optimisations to the program. |
+| @noStdlib@ | Include the Kotlin runtime libraries from KOTLIN_HOME in the classpath of the compiler. |
+| @target@ | Bytecode compatibility. |
+| @javac@ | Hash of options passed to the ant javac task. |
h2(#groovy). Groovy
@@ -527,7 +550,6 @@ The Groovy compiler supports the following options:
| @target@ | Bytecode compatibility. |
| @javac@ | Hash of options passed to the ant javac task. |
-
h3. Testing with Groovy
h4. EasyB
http://git-wip-us.apache.org/repos/asf/buildr/blob/509fb9a4/lib/buildr/kotlin.rb
----------------------------------------------------------------------
diff --git a/lib/buildr/kotlin.rb b/lib/buildr/kotlin.rb
new file mode 100644
index 0000000..7eace8f
--- /dev/null
+++ b/lib/buildr/kotlin.rb
@@ -0,0 +1,17 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with this
+# work for additional information regarding copyright ownership. The ASF
+# licenses this file to you 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.
+
+
+require 'buildr/kotlin/compiler'
http://git-wip-us.apache.org/repos/asf/buildr/blob/509fb9a4/lib/buildr/kotlin/compiler.rb
----------------------------------------------------------------------
diff --git a/lib/buildr/kotlin/compiler.rb b/lib/buildr/kotlin/compiler.rb
new file mode 100644
index 0000000..cbb504b
--- /dev/null
+++ b/lib/buildr/kotlin/compiler.rb
@@ -0,0 +1,282 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with this
+# work for additional information regarding copyright ownership. The ASF
+# licenses this file to you 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.
+
+# The Kotlin Module
+module Buildr::Kotlin
+ DEFAULT_VERSION = '1.1.3-2'
+
+ class << self
+
+ def installed_version
+ unless @installed_version
+ @installed_version = if Kotlinc.installed?
+ begin
+ # try to read the value from the build.txt file
+ version_str = File.read(File.expand_path('build.txt', Kotlinc.kotlin_home))
+
+ if version_str
+ md = version_str.match(/\d+\.\d[\d\.]*/) or
+ fail "Unable to parse Kotlin version: #{version_str}"
+
+ md[0].sub(/.$/, "") # remove trailing dot, if any
+ end
+ rescue => e
+ warn "Unable to parse library.properties in $KOTLIN_HOME/build.txt: #{e}"
+ nil
+ end
+ end
+ end
+
+ @installed_version
+ end
+
+ def version
+ Buildr.settings.build['kotlin.version'] || installed_version || DEFAULT_VERSION
+ end
+
+ # check if version matches any of the given prefixes
+ def version?(*v)
+ v.any? { |v| version.index(v.to_s) == 0 }
+ end
+
+ end
+
+ # Kotlin compiler:
+ # compile.using(:kotlin)
+ # Used by default if .kt files are found in the src/main/kotlin directory (or src/test/kotlin)
+ # and sets the target directory to target/classes (or target/test/classes).
+ # Accepts the following options:
+ # * :warnings -- Issue warnings when compiling. True when running in verbose mode.
+ # * :debug -- Generates bytecode with debugging information. Set from the debug
+ # environment variable/global option.
+ # * :optimize -- Optimize the byte code generation. False by default.
+ # * :target -- Bytecode compatibility.
+ # * :noStdlib -- Include the Kotlin runtime. False by default.
+ # * :javac -- Arguments for javac compiler.
+ class Kotlinc < Buildr::Compiler::Base
+
+ class << self
+ def kotlin_home
+ env_home = ENV['KOTLIN_HOME']
+
+ @home ||= if !env_home.nil? && File.exists?(env_home + '/lib/kotlin-compiler.jar')
+ env_home
+ else
+ nil
+ end
+ end
+
+ def installed?
+ !kotlin_home.nil?
+ end
+
+ def use_installed?
+ if installed? && Buildr.settings.build['kotlin.version']
+ Buildr.settings.build['kotlin.version'] == Kotlin.installed_version
+ else
+ Buildr.settings.build['kotlin.version'].nil? && installed?
+ end
+ end
+
+ def dependencies
+ kotlin_dependencies = if use_installed?
+ %w(kotlin-stdlib kotlin-compiler).map { |s| File.expand_path("lib/#{s}.jar", kotlin_home) }
+ else
+ REQUIRES.artifacts.map(&:to_s)
+ end
+ # Add Java utilities (eg KotlinMessageCollector)
+ kotlin_dependencies |= [ File.join(File.dirname(__FILE__)) ]
+ (kotlin_dependencies).compact
+ end
+
+ def applies_to?(project, task) #:nodoc:
+ paths = task.sources + [sources].flatten.map { |src| Array(project.path_to(:source, task.usage, src.to_sym)) }
+ paths.flatten!
+
+ # Just select if we find .kt files
+ paths.any? { |path| !Dir["#{path}/**/*.kt"].empty? }
+ end
+ end
+
+ # The kotlin compiler jars are added to classpath at load time,
+ # if you want to customize artifact versions, you must set them on the
+ #
+ # artifact_ns['Buildr::Compiler::Kotlinc'].library = '1.1.3-2'
+ #
+ # namespace before this file is required. This is of course, only
+ # if KOTLIN_HOME is not set or invalid.
+ REQUIRES = ArtifactNamespace.for(self) do |ns|
+ version = Buildr.settings.build['kotlin.version'] || DEFAULT_VERSION
+ ns.compiler! 'org.jetbrains.kotlin:kotlin-compiler:jar:>=' + version
+ end
+
+ Javac = Buildr::Compiler::Javac
+
+ OPTIONS = [:warnings, :optimize, :target, :debug, :noStdlib, :javac]
+
+ # Lazy evaluation to allow change in buildfile
+ Java.classpath << lambda { dependencies }
+
+ specify :language=>:kotlin, :sources => [:kotlin, :java], :source_ext => [:kt, :java],
+ :target=>'classes', :target_ext=>'class', :packaging=>:jar
+
+ def initialize(project, options) #:nodoc:
+ super
+ # use common options also for javac
+
+ options[:javac] ||= Buildr::Compiler::Javac::OPTIONS.inject({}) do |hash, option|
+ hash[option] = options[option]
+ hash
+ end
+
+ options[:debug] = Buildr.options.debug || trace?(:kotlinc) if options[:debug].nil?
+ options[:warnings] = verbose if options[:warnings].nil?
+ options[:optimize] = false if options[:optimize].nil?
+ options[:noStdlib] = true if options[:noStdlib].nil?
+ @java = Javac.new(project, options[:javac])
+ end
+
+
+
+ def compile(sources, target, dependencies) #:nodoc:
+ check_options(options, OPTIONS)
+
+ java_sources = java_sources(sources)
+
+ unless Buildr.application.options.dryrun
+ messageCollector = Java.org.apache.buildr.KotlinMessageCollector.new
+
+ Java.load
+ begin
+ compiler = Java.org.jetbrains.kotlin.cli.jvm.K2JVMCompiler.new
+ compilerArguments = kotlinc_args
+ compilerArguments.destination = File.expand_path(target)
+ compilerArguments.classpath = dependencies.join(File::PATH_SEPARATOR)
+ sources.each do |source|
+ compilerArguments.freeArgs.add(File.expand_path(source))
+ end
+ services = Buildr::Util.java_platform? ? Java.org.jetbrains.kotlin.config.Services::EMPTY : Java.org.jetbrains.kotlin.config.Services.EMPTY
+ compiler.exec(messageCollector, services, compilerArguments)
+ rescue => e
+ fail "Kotlin compiler crashed:\n#{e.inspect}"
+ end
+
+ unless java_sources.empty?
+ trace 'Compiling mixed Java/Kotlin sources'
+
+ deps = dependencies + Kotlinc.dependencies + [ File.expand_path(target) ]
+ @java.compile(java_sources, target, deps)
+ end
+ end
+ end
+
+ protected
+
+ # :nodoc: see Compiler:Base
+ def compile_map(sources, target)
+ target_ext = self.class.target_ext
+ ext_glob = Array(self.class.source_ext).join(',')
+ sources.flatten.map{|f| File.expand_path(f)}.inject({}) do |map, source|
+ sources = if File.directory?(source)
+ FileList["#{source}/**/*.{#{ext_glob}}"].reject { |file| File.directory?(file) }
+ else
+ [source]
+ end
+
+ sources.each do |source|
+ # try to extract package name from .java or .kt files
+ if %w(.java .kt).include? File.extname(source)
+ name = File.basename(source).split(".")[0]
+ package = findFirst(source, /^\s*package\s+([^\s;]+)\s*;?\s*/)
+ packages = count(source, /^\s*package\s+([^\s;]+)\s*;?\s*/)
+ found = findFirst(source, /((class)|(object))\s+(#{name})Kt/)
+
+ # if there's only one package statement and we know the target name, then we can depend
+ # directly on a specific file, otherwise, we depend on the general target
+ if (found && packages == 1)
+ map[source] = package ? File.join(target, package[1].gsub('.', '/'), name.ext(target_ext)) : target
+ else
+ map[source] = target
+ end
+
+ elsif
+ map[source] = target
+ end
+ end
+
+ map.each do |key,value|
+ map[key] = first_file unless map[key]
+ end
+
+ map
+ end
+ end
+
+ private
+
+ def count(file, pattern)
+ count = 0
+ File.open(file, 'r') do |infile|
+ while (line = infile.gets)
+ count += 1 if line.match(pattern)
+ end
+ end
+ count
+ end
+
+ def java_sources(sources)
+ sources.flatten.map { |source| File.directory?(source) ? FileList["#{source}/**/*.java"] : source } .
+ flatten.reject { |file| File.directory?(file) || File.extname(file) != '.java' }.map { |file| File.expand_path(file) }.uniq
+ end
+
+ # Returns Kotlinc arguments from the set of options.
+ def kotlinc_args #:nodoc:
+ compilerArguments = Java.org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments.new
+ compilerArguments.verbose = options[:debug]
+ compilerArguments.suppressWarnings = !options[:warnings]
+ compilerArguments.noStdlib = options[:noStdlib]
+ compilerArguments.noOptimize = !options[:optimize]
+ compilerArguments.reportOutputFiles = compilerArguments.verbose
+ compilerArguments.jvmTarget = options[:target] unless options[:target].nil?
+ compilerArguments
+ end
+ end
+
+ module ProjectExtension
+ def kotlinc_options
+ @kotlinc ||= KotlincOptions.new(self)
+ end
+ end
+
+ class KotlincOptions
+ attr_writer :incremental
+
+ def initialize(project)
+ @project = project
+ end
+
+ def incremental
+ @incremental || (@project.parent ? @project.parent.kotlinc_options.incremental : nil)
+ end
+ end
+end
+
+# Kotlin compiler comes first, ahead of Javac, this allows it to pick
+# projects that mix Kotlin and Java code by spotting Kotlin code first.
+Buildr::Compiler.compilers.unshift Buildr::Kotlin::Kotlinc
+
+class Buildr::Project #:nodoc:
+ include Buildr::Kotlin::ProjectExtension
+end
http://git-wip-us.apache.org/repos/asf/buildr/blob/509fb9a4/lib/buildr/kotlin/org/apache/buildr/KotlinMessageCollector$1.class
----------------------------------------------------------------------
diff --git a/lib/buildr/kotlin/org/apache/buildr/KotlinMessageCollector$1.class b/lib/buildr/kotlin/org/apache/buildr/KotlinMessageCollector$1.class
new file mode 100644
index 0000000..5bb12fd
Binary files /dev/null and b/lib/buildr/kotlin/org/apache/buildr/KotlinMessageCollector$1.class differ
http://git-wip-us.apache.org/repos/asf/buildr/blob/509fb9a4/lib/buildr/kotlin/org/apache/buildr/KotlinMessageCollector.class
----------------------------------------------------------------------
diff --git a/lib/buildr/kotlin/org/apache/buildr/KotlinMessageCollector.class b/lib/buildr/kotlin/org/apache/buildr/KotlinMessageCollector.class
new file mode 100644
index 0000000..958ef1d
Binary files /dev/null and b/lib/buildr/kotlin/org/apache/buildr/KotlinMessageCollector.class differ
http://git-wip-us.apache.org/repos/asf/buildr/blob/509fb9a4/lib/buildr/kotlin/org/apache/buildr/KotlinMessageCollector.java
----------------------------------------------------------------------
diff --git a/lib/buildr/kotlin/org/apache/buildr/KotlinMessageCollector.java b/lib/buildr/kotlin/org/apache/buildr/KotlinMessageCollector.java
new file mode 100644
index 0000000..cce8bfb
--- /dev/null
+++ b/lib/buildr/kotlin/org/apache/buildr/KotlinMessageCollector.java
@@ -0,0 +1,46 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to you 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.
+ */
+
+
+package org.apache.buildr;
+
+import org.jetbrains.kotlin.cli.common.messages.MessageCollector;
+import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity;
+import org.jetbrains.kotlin.cli.common.messages.CompilerMessageLocation;
+
+
+public class KotlinMessageCollector implements MessageCollector {
+
+ public void report(CompilerMessageSeverity severity, String message, CompilerMessageLocation location) {
+ switch(severity) {
+ case ERROR:
+ case EXCEPTION:
+ System.err.println((location != null ? (location.toString() + " ") : "") + message);
+ break;
+ default:
+ System.out.println((location != null ? (location.toString() + " ") : "") + message);
+ break;
+ }
+ }
+
+ public boolean hasErrors() {
+ return false;
+ }
+
+ public void clear() {
+ // not implemented
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/buildr/blob/509fb9a4/spec/kotlin/compiler_spec.rb
----------------------------------------------------------------------
diff --git a/spec/kotlin/compiler_spec.rb b/spec/kotlin/compiler_spec.rb
new file mode 100644
index 0000000..200f60a
--- /dev/null
+++ b/spec/kotlin/compiler_spec.rb
@@ -0,0 +1,274 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with this
+# work for additional information regarding copyright ownership. The ASF
+# licenses this file to you 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.
+
+
+require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helpers'))
+
+# need to test both with and without KOTLIN_HOME
+share_as :KotlincCompiler do
+
+ it 'should identify itself from source directories' do
+ write 'src/main/kotlin/com/example/Test.kt', "package com.example\n class Test { }"
+ define('foo').compile.compiler.should eql(:kotlinc)
+ end
+
+ it 'should report the language as :kotlin' do
+ define('foo').compile.using(:kotlinc).language.should eql(:kotlin)
+ end
+
+ it 'should set the target directory to target/classes' do
+ define 'foo' do
+ lambda { compile.using(:kotlinc) }.should change { compile.target.to_s }.to(File.expand_path('target/classes'))
+ end
+ end
+
+ it 'should not override existing target directory' do
+ define 'foo' do
+ compile.into('classes')
+ lambda { compile.using(:kotlinc) }.should_not change { compile.target }
+ end
+ end
+
+ it 'should not change existing list of sources' do
+ define 'foo' do
+ compile.from('sources')
+ lambda { compile.using(:kotlinc) }.should_not change { compile.sources }
+ end
+ end
+
+ it 'should include as classpath dependency' do
+ write 'src/dependency/Dependency.kt', 'class Dependency {}'
+ define 'dependency', :version=>'1.0' do
+ compile.from('src/dependency').into('target/dependency')
+ package(:jar)
+ end
+ write 'src/test/DependencyTest.kt', "class DependencyTest { val d = Dependency() }"
+ lambda { define('foo').compile.from('src/test').with(project('dependency')).invoke }.should run_task('foo:compile')
+ file('target/classes/DependencyTest.class').should exist
+ end
+
+ def define_test1_project
+ write 'src/main/kotlin/com/example/Test1.kt', "// file name: Test1.kt\npackage com.example\nclass Test1 {}"
+ define 'test1', :version=>'1.0' do
+ package(:jar)
+ end
+ end
+
+ it 'should compile a simple .kt file into a .class file' do
+ define_test1_project
+ task('test1:compile').invoke
+ file('target/classes/com/example/Test1.class').should exist
+ end
+
+ it 'should package .class into a .jar file' do
+ define_test1_project
+ task('test1:package').invoke
+ file('target/test1-1.0.jar').should exist
+ Zip::File.open(project('test1').package(:jar).to_s) do |zip|
+ zip.exist?('com/example/Test1.class').should be_true
+ end
+ end
+
+ it 'should compile kotlin class depending on java class in same project' do
+ write 'src/main/java/com/example/Foo.java', 'package com.example; public class Foo {}'
+ write 'src/main/kotlin/com/example/Bar.kt', "package com.example\n class Bar() : Foo() {}"
+ define 'test1', :version=>'1.0' do
+ package(:jar)
+ end
+ task('test1:package').invoke
+ file('target/test1-1.0.jar').should exist
+ Zip::File.open(project('test1').package(:jar).to_s) do |zip|
+ zip.exist?('com/example/Foo.class').should be_true
+ zip.exist?('com/example/Bar.class').should be_true
+ end
+ end
+
+ it 'should compile java class depending on kotlin class in same project' do
+ write 'src/main/kotlin/com/example/Foo.kt', 'package com.example; open class Foo'
+ write 'src/main/java/com/example/Bar.java', 'package com.example; public class Bar extends Foo {}'
+ define 'test1', :version=>'1.0' do
+ package(:jar)
+ end
+ task('test1:package').invoke
+ file('target/test1-1.0.jar').should exist
+ Zip::File.open(project('test1').package(:jar).to_s) do |zip|
+ zip.exist?('com/example/Foo.class').should be_true
+ zip.exist?('com/example/Bar.class').should be_true
+ end
+ end
+end
+
+share_as :KotlincCompiler_CommonOptions do
+
+ it 'should set warnings option to false by default' do
+ compile_task.options.warnings.should be_false
+ end
+
+ it 'should set warnings option to true when running with --verbose option' do
+ verbose true
+ compile_task.options.warnings.should be_true
+ end
+
+ it 'should use -nowarn argument when warnings is false' do
+ compile_task.using(:warnings=>false)
+ kotlinc_args.suppressWarnings.should be_true
+ end
+
+ it 'should not use -nowarn argument when warnings is true' do
+ compile_task.using(:warnings=>true)
+ kotlinc_args.suppressWarnings.should be_false
+ end
+
+ it 'should not use -verbose argument by default' do
+ oldDebug = Buildr.options.debug
+ Buildr.options.debug = false
+ begin
+ kotlinc_args.verbose.should eql(false)
+ ensure
+ Buildr.options.debug = oldDebug
+ end
+ end
+
+ it 'should use -verbose argument when running with --trace=kotlinc option' do
+ Buildr.application.options.trace_categories = [:kotlinc]
+ kotlinc_args.verbose.should eql(true)
+ end
+
+ it 'should set debug option to true by default' do
+ compile_task.options.debug.should be_true
+ end
+
+ it 'should set debug option to false based on Buildr.options' do
+ Buildr.options.debug = false
+ compile_task.options.debug.should be_false
+ end
+
+ it 'should set debug option to false based on debug environment variable' do
+ ENV['debug'] = 'no'
+ compile_task.options.debug.should be_false
+ end
+
+ it 'should set debug option to false based on DEBUG environment variable' do
+ ENV['DEBUG'] = 'no'
+ compile_task.options.debug.should be_false
+ end
+
+ it 'should set deprecation option to false by default' do
+ compile_task.options.deprecation.should be_false
+ end
+
+ it 'should set optimise option to false by default' do
+ compile_task.options.optimize.should be_false
+ end
+
+ it 'should use -optimise argument when deprecation is true' do
+ compile_task.using(:optimize=>true)
+ kotlinc_args.noOptimize.should be_false
+ end
+
+ it 'should not use -optimise argument when deprecation is false' do
+ compile_task.using(:optimize=>false)
+ kotlinc_args.noOptimize.should be_true
+ end
+
+ it 'should set noStdlib option to true by default' do
+ compile_task.options.noStdlib.should be_true
+ kotlinc_args.noStdlib.should be_true
+ end
+
+ it 'should not set target option by default' do
+ compile_task.options.target.should be_nil
+ kotlinc_args.jvmTarget.should be_nil
+ end
+
+ it 'should use -target:xxx argument if target option set' do
+ compile_task.using(:target=>'1.5')
+ kotlinc_args.jvmTarget.should eql('1.5')
+ end
+
+ it 'should not set other option by default' do
+ compile_task.options.other.should be_nil
+ end
+
+ it 'should complain about options it doesn\'t know' do
+ write 'source/Test.kt', 'class Test {}'
+ compile_task.using(:unknown=>'option')
+ lambda { compile_task.from('source').invoke }.should raise_error(ArgumentError, /no such option/i)
+ end
+
+ it 'should inherit options from parent' do
+ define 'foo' do
+ compile.using(:noStdlib=>false, :warnings=>true, :target=>'1.8')
+ define 'bar' do
+ compile.using(:kotlinc)
+ compile.options.noStdlib.should be_false
+ compile.options.warnings.should be_true
+ compile.options.target.should eql('1.8')
+ end
+ end
+ end
+
+ after do
+ Buildr.options.debug = nil
+ ENV.delete "debug"
+ ENV.delete "DEBUG"
+ end
+end
+
+if Java.java.lang.System.getProperty("java.runtime.version") >= "1.8"
+ # Only run this test if the test environment has KOTLIN_HOME specified.
+ # Allows the Test Suite to run on TravisCI
+ if ENV['KOTLIN_HOME']
+ describe 'kotlin compiler (installed in KOTLIN_HOME)' do
+ it 'requires present KOTLIN_HOME' do
+ ENV['KOTLIN_HOME'].should_not be_nil
+ end
+
+ def compile_task
+ @compile_task ||= define('foo').compile.using(:kotlinc)
+ end
+
+ it_should_behave_like KotlincCompiler
+ it_should_behave_like KotlincCompiler_CommonOptions
+ end
+ end
+
+ describe 'kotlin compiler (downloaded from repository)' do
+ old_home = ENV['KOTLIN_HOME']
+
+ before :all do
+ ENV['KOTLIN_HOME'] = nil
+ end
+
+ it 'requires absent KOTLIN_HOME' do
+ ENV['KOTLIN_HOME'].should be_nil
+ end
+
+ def compile_task
+ @compile_task ||= define('foo').compile.using(:kotlinc)
+ end
+
+ def kotlinc_args
+ compile_task.instance_eval { @compiler }.send(:kotlinc_args)
+ end
+
+ it_should_behave_like KotlincCompiler
+ it_should_behave_like KotlincCompiler_CommonOptions
+
+ after :all do
+ ENV['KOTLIN_HOME'] = old_home
+ end
+ end
+end
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/buildr/blob/509fb9a4/spec/sandbox.rb
----------------------------------------------------------------------
diff --git a/spec/sandbox.rb b/spec/sandbox.rb
index f5ef09a..6c3aa94 100644
--- a/spec/sandbox.rb
+++ b/spec/sandbox.rb
@@ -39,6 +39,7 @@ require 'buildr/groovy'
require 'buildr/scala'
require 'buildr/bnd'
require 'buildr/jaxb_xjc'
+require 'buildr/kotlin'
Java.load # Anything added to the classpath.
artifacts(