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 <[email protected]>
Authored: Sun Jul 23 23:22:14 2017 -0700
Committer: Antoine Toulme <[email protected]>
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(

Reply via email to