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(
