1 /* 2 * Copyright 2016 Google Inc. All Rights Reserved. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.google.turbine.options; 18 19 import static com.google.common.truth.Truth.assertThat; 20 import static com.google.common.truth.Truth8.assertThat; 21 import static org.junit.Assert.fail; 22 23 import com.google.common.collect.ImmutableList; 24 import com.google.common.collect.Iterables; 25 import java.nio.charset.StandardCharsets; 26 import java.nio.file.Files; 27 import java.nio.file.Path; 28 import java.util.Arrays; 29 import org.junit.Rule; 30 import org.junit.Test; 31 import org.junit.rules.TemporaryFolder; 32 import org.junit.runner.RunWith; 33 import org.junit.runners.JUnit4; 34 35 @RunWith(JUnit4.class) 36 public class TurbineOptionsTest { 37 38 @Rule public final TemporaryFolder tmpFolder = new TemporaryFolder(); 39 40 static final ImmutableList<String> BASE_ARGS = 41 ImmutableList.of("--output", "out.jar", "--target_label", "//java/com/google/test"); 42 43 @Test 44 public void exhaustiveArgs() throws Exception { 45 String[] lines = { 46 "--output", 47 "out.jar", 48 "--source_jars", 49 "sources1.srcjar", 50 "sources2.srcjar", 51 "--processors", 52 "com.foo.MyProcessor", 53 "com.foo.OtherProcessor", 54 "--processorpath", 55 "libproc1.jar", 56 "libproc2.jar", 57 "--classpath", 58 "lib1.jar", 59 "lib2.jar", 60 "--bootclasspath", 61 "rt.jar", 62 "zipfs.jar", 63 "--javacopts", 64 "-source", 65 "8", 66 "-target", 67 "8", 68 "--", 69 "--sources", 70 "Source1.java", 71 "Source2.java", 72 "--output_deps", 73 "out.jdeps", 74 "--target_label", 75 "//java/com/google/test", 76 "--injecting_rule_kind", 77 "foo_library", 78 }; 79 80 TurbineOptions options = 81 TurbineOptionsParser.parse(Iterables.concat(BASE_ARGS, Arrays.asList(lines))); 82 83 assertThat(options.output()).hasValue("out.jar"); 84 assertThat(options.sourceJars()) 85 .containsExactly("sources1.srcjar", "sources2.srcjar") 86 .inOrder(); 87 assertThat(options.processors()) 88 .containsExactly("com.foo.MyProcessor", "com.foo.OtherProcessor") 89 .inOrder(); 90 assertThat(options.processorPath()).containsExactly("libproc1.jar", "libproc2.jar").inOrder(); 91 assertThat(options.classPath()).containsExactly("lib1.jar", "lib2.jar").inOrder(); 92 assertThat(options.bootClassPath()).containsExactly("rt.jar", "zipfs.jar").inOrder(); 93 assertThat(options.javacOpts()).containsExactly("-source", "8", "-target", "8").inOrder(); 94 assertThat(options.sources()).containsExactly("Source1.java", "Source2.java"); 95 assertThat(options.outputDeps()).hasValue("out.jdeps"); 96 assertThat(options.targetLabel()).hasValue("//java/com/google/test"); 97 assertThat(options.injectingRuleKind()).hasValue("foo_library"); 98 assertThat(options.shouldReduceClassPath()).isTrue(); 99 } 100 101 @Test 102 public void strictJavaDepsArgs() throws Exception { 103 String[] lines = { 104 "--classpath", 105 "blaze-out/foo/libbar.jar", 106 "blaze-out/foo/libbaz1.jar", 107 "blaze-out/foo/libbaz2.jar", 108 "blaze-out/proto/libproto.jar", 109 "--direct_dependencies", 110 "blaze-out/foo/libbar.jar", 111 "--deps_artifacts", 112 "foo.jdeps", 113 "bar.jdeps", 114 "", 115 }; 116 117 TurbineOptions options = 118 TurbineOptionsParser.parse(Iterables.concat(BASE_ARGS, Arrays.asList(lines))); 119 120 assertThat(options.targetLabel()).hasValue("//java/com/google/test"); 121 assertThat(options.directJars()).containsExactly("blaze-out/foo/libbar.jar"); 122 assertThat(options.depsArtifacts()).containsExactly("foo.jdeps", "bar.jdeps"); 123 } 124 125 @Test 126 public void classpathArgs() throws Exception { 127 String[] lines = { 128 "--classpath", 129 "liba.jar", 130 "libb.jar", 131 "libc.jar", 132 "--processorpath", 133 "libpa.jar", 134 "libpb.jar", 135 "libpc.jar", 136 }; 137 138 TurbineOptions options = 139 TurbineOptionsParser.parse(Iterables.concat(BASE_ARGS, Arrays.asList(lines))); 140 141 assertThat(options.classPath()).containsExactly("liba.jar", "libb.jar", "libc.jar").inOrder(); 142 assertThat(options.processorPath()) 143 .containsExactly("libpa.jar", "libpb.jar", "libpc.jar") 144 .inOrder(); 145 } 146 147 @Test 148 public void repeatedClasspath() throws Exception { 149 String[] lines = { 150 "--classpath", 151 "liba.jar", 152 "libb.jar", 153 "libc.jar", 154 "--processorpath", 155 "libpa.jar", 156 "libpb.jar", 157 "libpc.jar", 158 }; 159 160 TurbineOptions options = 161 TurbineOptionsParser.parse(Iterables.concat(BASE_ARGS, Arrays.asList(lines))); 162 163 assertThat(options.classPath()).containsExactly("liba.jar", "libb.jar", "libc.jar").inOrder(); 164 assertThat(options.processorPath()) 165 .containsExactly("libpa.jar", "libpb.jar", "libpc.jar") 166 .inOrder(); 167 } 168 169 @Test 170 public void optionalTargetLabel() throws Exception { 171 String[] lines = { 172 "--output", 173 "out.jar", 174 "--classpath", 175 "liba.jar", 176 "libb.jar", 177 "libc.jar", 178 "--processorpath", 179 "libpa.jar", 180 "libpb.jar", 181 "libpc.jar", 182 }; 183 184 TurbineOptions options = TurbineOptionsParser.parse(Arrays.asList(lines)); 185 186 assertThat(options.targetLabel()).isEmpty(); 187 assertThat(options.injectingRuleKind()).isEmpty(); 188 } 189 190 @Test 191 public void paramsFile() throws Exception { 192 Iterable<String> paramsArgs = 193 Iterables.concat( 194 BASE_ARGS, Arrays.asList("--javacopts", "-source", "8", "-target", "8", "--")); 195 Path params = tmpFolder.newFile("params.txt").toPath(); 196 Files.write(params, paramsArgs, StandardCharsets.UTF_8); 197 198 // @ is a prefix for external repository targets, and the prefix for params files. Targets 199 // are disambiguated by prepending an extra @. 200 String[] lines = { 201 "@" + params.toAbsolutePath(), "--target_label", "//custom/label", 202 }; 203 204 TurbineOptions options = TurbineOptionsParser.parse(Arrays.asList(lines)); 205 206 // assert that options were read from params file 207 assertThat(options.javacOpts()).containsExactly("-source", "8", "-target", "8").inOrder(); 208 // ... and directly from the command line 209 assertThat(options.targetLabel()).hasValue("//custom/label"); 210 } 211 212 @Test 213 public void escapedExternalRepositoryLabel() throws Exception { 214 // @ is a prefix for external repository targets, and the prefix for params files. Targets 215 // are disambiguated by prepending an extra @. 216 String[] lines = { 217 "--target_label", "@@other-repo//foo:local-jam", 218 }; 219 220 TurbineOptions options = 221 TurbineOptionsParser.parse(Iterables.concat(BASE_ARGS, Arrays.asList(lines))); 222 223 assertThat(options.targetLabel()).hasValue("@other-repo//foo:local-jam"); 224 } 225 226 @Test 227 public void tolerateMissingOutput() throws Exception { 228 TurbineOptions options = TurbineOptions.builder().build(); 229 assertThat(options.output()).isEmpty(); 230 } 231 232 @Test 233 public void paramsFileExists() throws Exception { 234 String[] lines = { 235 "@/NOSUCH", "--javacopts", "-source", "7", "--", 236 }; 237 AssertionError expected = null; 238 try { 239 TurbineOptionsParser.parse(Arrays.asList(lines)); 240 } catch (AssertionError e) { 241 expected = e; 242 } 243 if (expected == null) { 244 fail(); 245 } 246 assertThat(expected).hasMessageThat().contains("params file does not exist"); 247 } 248 249 @Test 250 public void emptyParamsFiles() throws Exception { 251 Path params = tmpFolder.newFile("params.txt").toPath(); 252 Files.write(params, new byte[0]); 253 String[] lines = { 254 "--sources", "A.java", "@" + params.toAbsolutePath(), "B.java", 255 }; 256 TurbineOptions options = 257 TurbineOptionsParser.parse(Iterables.concat(BASE_ARGS, Arrays.asList(lines))); 258 assertThat(options.sources()).containsExactly("A.java", "B.java").inOrder(); 259 } 260 261 @Test 262 public void javacopts() throws Exception { 263 String[] lines = { 264 "--javacopts", "--release", "9", "--", "--sources", "Test.java", 265 }; 266 267 TurbineOptions options = 268 TurbineOptionsParser.parse(Iterables.concat(BASE_ARGS, Arrays.asList(lines))); 269 270 assertThat(options.javacOpts()).containsExactly("--release", "9").inOrder(); 271 assertThat(options.sources()).containsExactly("Test.java"); 272 } 273 274 @Test 275 public void unknownOption() throws Exception { 276 try { 277 TurbineOptionsParser.parse(Iterables.concat(BASE_ARGS, Arrays.asList("--nosuch"))); 278 fail(); 279 } catch (IllegalArgumentException e) { 280 assertThat(e).hasMessageThat().contains("unknown option"); 281 } 282 } 283 284 @Test 285 public void unterminatedJavacopts() throws Exception { 286 try { 287 TurbineOptionsParser.parse( 288 Iterables.concat(BASE_ARGS, Arrays.asList("--javacopts", "--release", "8"))); 289 fail(); 290 } catch (IllegalArgumentException e) { 291 assertThat(e).hasMessageThat().contains("javacopts should be terminated by `--`"); 292 } 293 } 294 295 @Test 296 public void releaseJavacopts() throws Exception { 297 TurbineOptions options = 298 TurbineOptionsParser.parse( 299 Iterables.concat( 300 BASE_ARGS, 301 Arrays.asList( 302 "--release", 303 "9", 304 "--javacopts", 305 "--release", 306 "8", 307 "--release", 308 "7", 309 "--release", 310 "--"))); 311 assertThat(options.release()).hasValue("7"); 312 assertThat(options.javacOpts()) 313 .containsExactly("--release", "8", "--release", "7", "--release") 314 .inOrder(); 315 } 316 317 @Test 318 public void shouldReduceClasspath() throws Exception { 319 { 320 TurbineOptions options = 321 TurbineOptionsParser.parse( 322 Iterables.concat(BASE_ARGS, ImmutableList.of("--reduce_classpath"))); 323 assertThat(options.shouldReduceClassPath()).isTrue(); 324 } 325 326 { 327 TurbineOptions options = 328 TurbineOptionsParser.parse( 329 Iterables.concat(BASE_ARGS, ImmutableList.of("--noreduce_classpath"))); 330 assertThat(options.shouldReduceClassPath()).isFalse(); 331 } 332 } 333 334 @Test 335 public void unescape() throws Exception { 336 String[] lines = { 337 "--sources", "Test.java", "'Foo$Bar.java'", 338 }; 339 TurbineOptions options = 340 TurbineOptionsParser.parse(Iterables.concat(BASE_ARGS, Arrays.asList(lines))); 341 assertThat(options.sources()).containsExactly("Test.java", "Foo$Bar.java").inOrder(); 342 } 343 344 @Test 345 public void invalidUnescape() throws Exception { 346 String[] lines = {"--sources", "'Foo$Bar.java"}; 347 try { 348 TurbineOptionsParser.parse(Iterables.concat(BASE_ARGS, Arrays.asList(lines))); 349 fail(); 350 } catch (IllegalArgumentException expected) { 351 } 352 } 353 } 354